Skip to content
This repository

Overview

ObjectFabric's main proposition is to add versioning to Web resources, by keeping track of each change in an append-only way instead of updating resources in-place.

objectfabric.org

API

ObjectFabric main classes are Resource, Workspace, and Location.

The system can do a better job at synchronization if it has some understanding of an application's data. For this reason ObjectFabric provides abstractions like collections, arrays and counters. It exposes them using a convenient type for each platform, e.g. a java.util.Set on the JVM.

JavaDoc. The API is mostly the same on JavaScript and .NET.

Implementations

Shared

ObjectFabric is primarily written as a Java library. It is symmetric between clients and servers, lightweight, and does not have dependencies, so that it can be recompiled to other platforms. Google Web Toolkit exports it to JavaScript for browsers and Node.js, and IKVM to .NET and Mono.

All implementations allow resources to contain primitives like strings, collections like maps, arrays, and counters. They use their platform's conventions for base types, naming, callbacks etc, and can interoperate with any of the others.

Road Map

  • Expose synchronization conflicts for user resolution.
  • Support iOS using maybe J2ObjC or MonoTouch

JavaScript

  • Supports primitives: strings, booleans, and numbers (mapped to doubles on other platforms).
  • Collections are mapped to custom objects, check sample for usage.
  • Caching and off-line support using IndexedDB.
  • Server using Node.js.

Non-immutable types have callbacks for change notification, e.g. for a map

map.onput(function(key) {
  var newValue = map.get(key);
});

Package for node with samples

objectfabric-js.zip

Road Map

  • Comet fallback for old browsers

JVM - GWT - Android

  • Supports primitives listed in Immutable.
  • Collections are exposed as java.util.Set, java.util.Map and generated array equivalents.
  • Custom objects can be defined through code generation for more complex data models.
  • Resources can be stored in SQLite, IndexedDB or file system.
  • Simple API for other stores and data formats.
  • Server using Netty.

Non-immutable types have listeners for change notification, e.g. for a map

map.addListener(new AbstractKeyListener() {
    // A key has been put in the map
    public void onPut(Object key) {
        Object newValue = map.get(key);
    }
}

Maven

<dependency>
  <groupId>org.objectfabric</groupId>
  <artifactId>objectfabric</artifactId>
  <version>0.9.1</version>
</dependency>

Samples

  • master
  • zip (points to latest release, use this one to get dependencies resolved by Maven, e.g. in Eclipse: File -> Import -> Maven -> Existing Maven Projects -> objectfabric.examples. Should be all set.)

Road Map

  • Packaging as a servlet
  • Basic clustering support (alpha)

.NET

  • Supports primitives listed in Immutable.
  • Collections are mapped to IDictionary, ISet and a generic array equivalent.
  • Custom objects can be defined through code generation for more complex data models.
  • Data binding (objects implement INotifyPropertyChanged and INotifyCollectionChanged)

Non-immutable types have events for change notification, e.g. for a map

dictionary.Added += key =>
{
    object newValue = dictionary[key]);
};

Road Map

  • Offline support using SQLite
  • Server using .NET 4.5 WebSockets
  • WinRT support

Internals

Loading Resources

Loading a resource requires listing changes for a URI, e.g. by listing files in a folder if loading locally. This is not built-in to HTTP, so loading a remote resource requires e.g. a custom REST endpoint, WebDAV, or one of OF server implementations.

Clients must merge changes to get the actual data, e.g. using tools for JSON Patch. OF performs this internally, under a simple REST-like API.

Ordering

Changes must be merged by clients in the right order. This could be done using timestamps, but to be usable e.g. on the Web, where machines might not have accurate clocks, OF adds vector clock information to each change. The algorithm is derived from NoSQL stores, and uses a UID per client, which is cached with resources, e.g. using IndexedDB on browsers.

When a resource is modified, the client increments a counter and adds it with its UID to the change description. It also adds UIDs and associated counters of all other known writers of this resource. When another process receives the change, it can insert it at the right position relative to the ones already loaded, and determine what data to keep or to discard during merge.

This allows changes to propagate in any order through the cloud, or to be stored by offline clients for some time, and still be merged correctly. When the vector clock determines that changes have been made concurrently, there might be conflicts. The current policy is to choose the change with the highest UID, which is deterministic between machines, to make OF eventually consistent. In some cases is would be useful to expose conflicts and let the user pick a version.

Data Format

Resource versions are currently represented using a binary protocol for efficiency and because OF is present on both ends. For storage and interoperability it would be easy to use JSON Patch instead.

Something went wrong with that request. Please try again.