ovsdb: Flush JSON cache only when necessary
[cascardo/ovs.git] / ovsdb / jsonrpc-server.c
index 5514897..fffcb73 100644 (file)
@@ -89,6 +89,9 @@ static struct jsonrpc_msg *ovsdb_jsonrpc_monitor_cancel(
 static void ovsdb_jsonrpc_monitor_remove_all(struct ovsdb_jsonrpc_session *);
 static void ovsdb_jsonrpc_monitor_flush_all(struct ovsdb_jsonrpc_session *);
 static bool ovsdb_jsonrpc_monitor_needs_flush(struct ovsdb_jsonrpc_session *);
+static struct json *ovsdb_jsonrpc_monitor_compose_update(
+    struct ovsdb_jsonrpc_monitor *monitor, bool initial);
+
 \f
 /* JSON-RPC database server. */
 
@@ -1034,6 +1037,8 @@ struct ovsdb_jsonrpc_monitor {
     struct hmap_node node;      /* In ovsdb_jsonrpc_session's "monitors". */
     struct json *monitor_id;
     struct ovsdb_monitor *dbmon;
+    uint64_t unflushed;         /* The first transaction that has not been
+                                       flushed to the jsonrpc remote client. */
 };
 
 static struct ovsdb_jsonrpc_monitor *
@@ -1152,6 +1157,7 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db,
                              const struct json *request_id)
 {
     struct ovsdb_jsonrpc_monitor *m = NULL;
+    struct ovsdb_monitor *dbmon = NULL;
     struct json *monitor_id, *monitor_requests;
     struct ovsdb_error *error = NULL;
     struct shash_node *node;
@@ -1178,6 +1184,7 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db,
     m->session = s;
     m->db = db;
     m->dbmon = ovsdb_monitor_create(db, m);
+    m->unflushed = 0;
     hmap_insert(&s->monitors, &m->node, json_hash(monitor_id, 0));
     m->monitor_id = json_clone(monitor_id);
 
@@ -1228,8 +1235,18 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db,
         }
     }
 
-    return jsonrpc_create_reply(ovsdb_monitor_get_initial(m->dbmon),
-                                request_id);
+    dbmon = ovsdb_monitor_add(m->dbmon);
+    if (dbmon != m->dbmon) {
+        /* Found an exisiting dbmon, reuse the current one. */
+        ovsdb_monitor_remove_jsonrpc_monitor(m->dbmon, m);
+        ovsdb_monitor_add_jsonrpc_monitor(dbmon, m);
+        m->dbmon = dbmon;
+    }
+
+    ovsdb_monitor_get_initial(m->dbmon);
+    json = ovsdb_jsonrpc_monitor_compose_update(m, true);
+    json = json ? json : json_object_create();
+    return jsonrpc_create_reply(json, request_id);
 
 error:
     if (m) {
@@ -1274,10 +1291,10 @@ ovsdb_jsonrpc_monitor_remove_all(struct ovsdb_jsonrpc_session *s)
 }
 
 static struct json *
-ovsdb_jsonrpc_monitor_compose_table_update(
-    const struct ovsdb_jsonrpc_monitor *monitor, bool initial)
+ovsdb_jsonrpc_monitor_compose_update(struct ovsdb_jsonrpc_monitor *m,
+                                     bool initial)
 {
-    return ovsdb_monitor_compose_table_update(monitor->dbmon, initial);
+    return ovsdb_monitor_get_update(m->dbmon, initial, &m->unflushed);
 }
 
 static bool
@@ -1286,7 +1303,7 @@ ovsdb_jsonrpc_monitor_needs_flush(struct ovsdb_jsonrpc_session *s)
     struct ovsdb_jsonrpc_monitor *m;
 
     HMAP_FOR_EACH (m, node, &s->monitors) {
-        if (ovsdb_monitor_needs_flush(m->dbmon)) {
+        if (ovsdb_monitor_needs_flush(m->dbmon, m->unflushed)) {
             return true;
         }
     }
@@ -1299,7 +1316,7 @@ ovsdb_jsonrpc_monitor_destroy(struct ovsdb_jsonrpc_monitor *m)
 {
     json_destroy(m->monitor_id);
     hmap_remove(&m->session->monitors, &m->node);
-    ovsdb_monitor_destroy(m->dbmon);
+    ovsdb_monitor_remove_jsonrpc_monitor(m->dbmon, m);
     free(m);
 }
 
@@ -1311,7 +1328,7 @@ ovsdb_jsonrpc_monitor_flush_all(struct ovsdb_jsonrpc_session *s)
     HMAP_FOR_EACH (m, node, &s->monitors) {
         struct json *json;
 
-        json = ovsdb_jsonrpc_monitor_compose_table_update(m, false);
+        json = ovsdb_jsonrpc_monitor_compose_update(m, false);
         if (json) {
             struct jsonrpc_msg *msg;
             struct json *params;