Optra ===== [![Build Status](https://travis-ci.org/dyule/optra.svg?branch=master)](https://travis-ci.org/dyule/optra) Optra is a Rust package allowing for remote file synchronization. It provides the algorithms necessary to keep files in sync, but not the transmission or file change detection needed. These are provided by [wamp-rs](https://github.com/dyule/wamp-rs) and [rdiff](https://github.com/dyule/rdiff) respectively, or you can use your own mechanism. Optra currently requires nightly rust to build, because it uses in place insertion into linked lists, which is feature gated (see [the docs](https://doc.rust-lang.org/std/collections/linked_list/struct.IterMut.html)) for more. Optra is licensed using the MIT license (see [LICENSE](LICENSE)) [Documentation](https://dyule.github.io/optra/optra/) # Usage The engine is based on the Admissabilty Based Sequence Transformation algorithm (doi: [10.1109/TPDS.2010.64](http://dx.doi.org.ezproxy.library.dal.ca/10.1109/TPDS.2010.64)), which is a type of Operational Transformation. The idea is that each site that wants to have a file synchronized will have an instance of [`Engine`](engine/struct.Engine.html) running. Any changes that are made to teh file should be run through the engine using either `process_diffs()` or `process_transaction()` prior to being broadcast. Any changes that are made at a remote site should be run through the engine using `integrate_remote()` prior to being applied to the file. This crate generally works well with [`rdiff`](https://crates.io/crates/rdiff), but can work with any system that generates difference operations that are limited to insert and delete. To use simply include ```toml [dependencies] optra = "^0.2" ``` in your `Cargo.toml` file Examples Assuming you have a method `read_transaction` for reading transactions from remote sites, the process for integrating remote changes onto a local file go like this: ```rust let (mut remote_sequence, remote_lookup) = read_transaction(); engine.integrate_remote(&mut remote_sequence, &remote_lookup, &mut time_stamper); let mut file = OpenOptions::new() .read(true) .write(true) .open("local_file") .unwrap(); remote_sequence.apply(&mut file).unwrap(); ``` On the other hand, if you have a Diff generated by detecting differences to a local file, you can process the diff and then send it out (assuming you have a method called `send_transaction()`) ```rust let diffs = file_hashes.diff_and_update(File::open("local_file").unwrap()).unwrap(); let (transaction, lookup) = engine.process_diffs(diffs, &mut time_stamper); send_transaction(transaction, lookup); ```