Skip to content
/ orda Public

Orda: A client and server written in Go. CRDT-based data synchronization supporting document database.

License

Notifications You must be signed in to change notification settings

orda-io/orda

Repository files navigation

🐎🎪Orda



    .::::                 .::          
  .::    .::              .::          
.::        .::.: .:::     .::   .::    
.::        .:: .::    .:: .:: .::  .:: 
.::        .:: .::   .:   .::.::   .:: 
  .::     .::  .::   .:   .::.::   .:: 
    .::::     .:::    .:: .::  .:: .:::
                                          

Orda (or ordu, ordo, or ordon) means the Mongolian mobile tent or place tent. As stated in Civilization WIKI, Orda (or Ordu) was the center of the tribe for the nomadic Mongolians. Orda project is a multi-device data synchronization platform based on MongoDB (which could be other document databases such as CouchBase). Orda is based on CRDT(conflict-free data types), which enables operation-based synchronization.

This project is mainly based on these two papers.

Concepts

  • Using Orda SDKs, you can allow multiple users to synchronize any document in a collection of DocumentDB.

!

  • Any field can be added, removed and updated using JSON operations.
  • For example, Orda-JSONEditor implemented with Orda-js allows multiple users concurrently to edit any document in a collection of MongoDB as the following picture.

ezgif com-gif-maker

  • You can see the full video of the example usage of Orda JSONEditor At YouTube here.

  • The documents in the MongoDB collection can be used for the analytics or read-only workloads. It is not recommended modifying them directly.

Working environment

  • go 1.18
  • docker latest, docker-compose (for building and deploying local orda-server)
  • protobuf / grpc / grpc-gateway
  • MongoDB latest
  • MQTT: EQM
  • Redis latest
  • Maybe work on lower versions of them

Getting started

Install

$ git clone https://github.com/orda-io/orda.git
$ cd orda
$ make init # generate builder container
$ make protoc-gen # generate protobuf codes

Run Orda Server

  • You can run orda server with docker-compose.
 $ make build-docker-server
 $ make docker-up
 $ docker ps 
  • Port mapping in docker-compose
    • orda-server
      • 19061: for gRPC protocol
      • 19861: for HTTP REST control (swagger)
    • orda-mongodb
      • 27017
    • orda-emqx
      • 18181(host):1883(internal) : for MQTT
      • 18881(host):8083(internal) : for websocket / HTTP
      • 18081(host):18083(internal) : for dashboard
    • orda-redis
      • 16379(host):6379(internal) : for client

Make a collection

  • To make Orda clients connect to Orda server, a collection should be prepared in MongoDB.
  • The collection is going to create a real collection of MongoDB.
  • It can be created by restful API: curl -X GET http://<SERVER_ADDR>/api/v1/collections/<COLLECTION_NAME>
  • The collections can be created and reset by the swagger.
 $ curl -s -X PUT http://localhost:19861/api/v1/collections/hello_world
Created collection 'hello_world(1)'

Use Orda client SDK

Make a client

  • An Orda client manages the connection with the Orda server and synchronization of Orda datatypes.
  • An Orda client participates in a collection of MongoDB, which means that the snapshot of any created datatype is written to the collection of MongoDB.
  • The orda client package should be imported as follows.
$ cd YOUR_PORJECT_PACKAGE
$ go get -u github.com/orda-io/orda/client
  • To create client, you
clientConf := &orda.ClientConfig{
ServerAddr:       "localhost:19061", // Orda Server address.
NotificationAddr: "localhost:11883", // notification server address.
CollectionName:   "hello_world", // the collection name of MongoDB which the client participates in.
SyncType:         model.SyncType_REALTIME, // syncType that is notified in real-time from notification server.
}

client1 := orda.NewClient(clientConf, "client1") // create a client with alias "client1".
if err := client1.Connect(); err != nil {         // connect to Orda server
    _ = fmt.Errorf("fail client to connect an Orda server: %v", err.Error())
    return
}

defer func() {
    if err := client1.Close(); err != nil { // close the client
        _ = fmt.Errorf("fail to close client: %v", err.Error())
    }
}()

Use Datatypes

Creation and Subscription of Datatypes

  • For using datatypes, a client should create or subscribe datatypes.
  • A datatype has a key which is used as a document ID; i.e., `_id' of MongoDB document.
  • There are three ways to use a datatype. For a type of datatype XXXX, XXXX cam be one of IntCounter, HashMap, List...
// CreateXXXX() is used to create a new datatype. 
// If there already exists a datatype for the key, it returns an error via error handler.
Counter := client.CreateCounter("key", orda.NewHandlers(...)

// SubscribeXXXX() is used to subscribe an existing datatype. 
// If there exists no datatype for the key, it returns an error via error handler
Counter := client.SubscribeCounter("key", orda.NewHandlers(...)

// SubscribeOrCreateXXXX() is used to subscribe an existing datatype. 
// If no datatype exists for the key, a new datatype is created. 
// It is recommended to use this method to shorten code lines.
Counter := client.SubscribeOrCreateCounter("key", orda.NewHandlers(...)

// Client should sync with Orda server.
if err := client.Sync(); err !=nil {
panic(err)
}

Contribute to Orda Project


We always welcome your participation. Please see contributing doc. If you're also interested in writing academic papers with our orda implementations such as JSON CRDTs, feel free contact us:

License


Orda is licensed under Apache 2.0 License that can be found in the LICENSE file.