# mco_iot_replicator_sync

Start the node's synchronization.

### For an overview see page ARF Applications in C

### Prototype

        MCO_RET mco_iot_replicator_sync(mco_iot_replicator_h repl,
                            mco_iot_agent_id_t agent_id,
                            int flags);

### Arguments

repl | The replicator object
agent_id | The `device_id` to synchronize or `one of the following constants:`
`MCO_IOT_ALL_AGENTS` | Synchronize all connected devices
`MCO_IOT_SERVER_AGENT_ID` | Denotes the server node
`MCO_IOT_ALL_UP_AGENTS` | All directly or indirectly connected nodes with a lower level value
`MCO_IOT_ALL_DOWN_AGENTS` | All directly or indirectly connected nodes with a higher level value
flags | The bitmask value of a combination of the following synchronization flags:
MCO_IOT_SYNC_PUSH | Send (push out) modification to a node (or to all nodes). The server sends all modified data from downtable classes, while the device sends all modified data from its uptable classes
MCO_IOT_SYNC_PULL | Request modifications from remote nodes
MCO_IOT_SYNC_NONBLOCK | Ensure that the socket is not blocking (a memory buffer is used when the socket is blocked to temporarily cache transmission requests)
MCO_IOT_SYNC_WAIT | Wait until the requested operations complete. If the request is to push (`MCO_IOT_SYNC_PUSH`) then wait until `ACK` is received from the remote node; if the request is to pull (`MCO_IOT_SYNC_PULL`) then wait until all data is received
MCO_IOT_SYNC_BOTH | Equivalent to `MCO_IOT_SYNC_PUSH | MCO_IOT_SYNC_PULL`
MCO_IOT_SYNC_DEEP_ACK | If set, the data must be acknowledged by the destination node. This ensures that the destination has received the data but can delay receiving ACK if the destination is busy or not available. If this flag not set, the data acknowledged by the directly connected node (router). Later, the router will deliver data to the destination.
MCO_IOT_SYNC_RESEND | Usually mco_iot_replicator_sync() doesn't re-send data that was already sent but not ACKed. This flag forces to resend all non-ACKed data. This can be useful if the position of the node in the ioT network was changed.
MCO_IOT_SYNC_CHILDS | If set, the data is delivered to the destination node and all its direct and indirect children.

### Description

The function starts the node's synchronization. Note that:

> a ) If the `MCO_IOT_SYNC_WAIT` flag is not set, the function returns immediately after the data is written to the socket. The subsequent events, receiving ack for the push and data for the pull, must be handled in the callbacks

> b) The flags `MCO_IOT_SYNC_NONBLOCK` and `MCO_IOT_SYNC_WAIT` are incompatible

> c) The flag `MCO_IOT_SYNC_WAIT` is not allowable when the `agent_id` is `MCO_IOT_ALL_AGENTS` (it can’t synchronously wait for all agents to respond)

### Return Codes

MCO_S_OK | Synchronization successfully started
MCO_S_IOT_NO_NEW_DATA | No new data were inserted or updated since the previous call of `mco_iot_replicator_sync()`. Note that this is not error but status code
MCO_E_IOT_INVALID_HANDLE | Invalid replicator handle `repl`
MCO_E_ILLEGAL_PARAM | Incompatible parameter values (e.g. neither `PULL` nor `PUSH` specified; `NONBLOCK` and `WAIT` specified together etc.)
MCO_E_IOT_WRONG_AGENT_ID | The `agent_id` is not valid
MCO_E_IOT_AGENT_NOT_FOUND | The device or server with the specified `agent_id` was not found
MCO_E_NOMEM | Unable to allocate memory for internal structures
MCO_E_WRITE_STREAM | Unable to write the replicated data to the socket
MCO_E_SESLIMIT | Or other `connect()` errors if the function can't create a database connection
`mco_trans_start()` errors | Error starting a transaction
``mco_trans_commit()`` errors | Error committing a transaction
other errors | Other errors can happen when accessing database to serialize changes

### Example

The code snippet below initializes the ARF (IoT) runtime, opens and connects the database, creates the communicator and replicator objects, then connects and synchronizes the replicator:

        int main(int argc, char *argv[])
        {
            mco_db_params_t db_params;
            mco_device_t dev;
            mco_db_h db;
            mco_iot_replicator_params_t repl_params;
            mco_iot_comm_params_t comm_params;
            mco_iot_replicator_h repl;
            mco_iot_comm_h comm;
            const char *conn_string = (argc > 1) ? argv[1] : "127.0.0.1:15000";
            ...

            /* Initialize eXtremeDB and IoT runtimes */
            mco_error_set_handler(&sample_errhandler);
            mco_runtime_start();
            mco_iot_init();

            /* Create database */
            dev.type       = MCO_MEMORY_CONV;
            dev.assignment = MCO_MEMORY_ASSIGN_DATABASE;
            dev.size       = DEVICE_DATABASE_SIZE;
            dev.dev.conv.ptr = (void*)malloc(dev.size);
            mco_db_params_init (&db_params);
            db_params.db_max_connections = 5;

            if (argc > 2) {
                db_params.iot_agent_id = atoi(argv[2]); /* Override the agent_id in the schema */
            }
            CHECK(mco_db_open_dev(db_name, iotdevice_get_dictionary(), &dev, 1, &db_params));
            CHECK(mco_db_connect(db_name, &db));
            mco_iot_comm_params_init(&comm_params);
            CHECK(mco_iot_comm_create(&comm_params, &comm));
            mco_iot_replicator_params_init(&repl_params);
            CHECK(mco_iot_replicator_create(db, comm, &repl_params, &repl));
            ...
            CHECK(mco_iot_replicator_connect(repl, conn_string, 2*1000, 0));
            ...
            CHECK(mco_iot_replicator_sync(repl, MCO_IOT_SERVER_AGENT_ID, MCO_IOT_SYNC_PULL | MCO_IOT_SYNC_PUSH | MCO_IOT_SYNC_WAIT));
        }

### Files

Header file:
mcoiot.h
Source file:
mcoiotrepl.c
Library:
libmcoiotrepl.a