diff --git a/light9/rdfdb/autodepgraphapi.py b/light9/rdfdb/autodepgraphapi.py --- a/light9/rdfdb/autodepgraphapi.py +++ b/light9/rdfdb/autodepgraphapi.py @@ -5,11 +5,14 @@ log = logging.getLogger('syncedgraph') class AutoDepGraphApi(object): """ + knockoutjs-inspired API for automatically building a dependency + tree while reading the graph. See addHandler(). + mixin for SyncedGraph, separated here because these methods work together """ def __init__(self): - self._watchers = GraphWatchers() + self._watchers = _GraphWatchers() self.currentFuncs = [] # stack of addHandler callers def addHandler(self, func): @@ -102,7 +105,7 @@ class AutoDepGraphApi(object): # subjects(RDF.type, t) call -class GraphWatchers(object): +class _GraphWatchers(object): """ store the current handlers that care about graph changes """ diff --git a/light9/rdfdb/currentstategraphapi.py b/light9/rdfdb/currentstategraphapi.py --- a/light9/rdfdb/currentstategraphapi.py +++ b/light9/rdfdb/currentstategraphapi.py @@ -2,7 +2,10 @@ from rdflib import ConjunctiveGraph from light9.rdfdb.rdflibpatch import contextsForStatement as rp_contextsForStatement class CurrentStateGraphApi(object): - + """ + mixin for SyncedGraph, separated here because these methods work together + """ + def currentState(self, context=None): """ a graph you can read without being in an addHandler diff --git a/light9/rdfdb/grapheditapi.py b/light9/rdfdb/grapheditapi.py --- a/light9/rdfdb/grapheditapi.py +++ b/light9/rdfdb/grapheditapi.py @@ -5,6 +5,8 @@ from light9.rdfdb.patch import Patch class GraphEditApi(object): """ + fancier graph edits + mixin for SyncedGraph, separated here because these methods work together """ diff --git a/light9/rdfdb/patchreceiver.py b/light9/rdfdb/patchreceiver.py --- a/light9/rdfdb/patchreceiver.py +++ b/light9/rdfdb/patchreceiver.py @@ -10,19 +10,25 @@ class PatchReceiver(object): master. See onPatch for what happens when the rdfdb master sends us a patch """ - def __init__(self, label, graph, initiallySynced): + def __init__(self, graph, label, initiallySynced): + """ + label is what we'll call ourselves to the rdfdb server + + initiallySynced is a deferred that we'll call back when we get + the first patch from the server + """ self.graph = graph self.initiallySynced = initiallySynced listen = reactor.listenTCP(0, cyclone.web.Application(handlers=[ - (r'/update', makePatchEndpoint(self.onPatch)), + (r'/update', makePatchEndpoint(self._onPatch)), ])) port = listen._realPortNumber # what's the right call for this? self.updateResource = 'http://localhost:%s/update' % port log.info("listening on %s" % port) - self.register(label) + self._register(label) - def onPatch(self, p): + def _onPatch(self, p): """ central server has sent us a patch """ @@ -39,7 +45,7 @@ class PatchReceiver(object): self.initiallySynced.callback(None) self.initiallySynced = None - def register(self, label): + def _register(self, label): def done(x): log.debug("registered with rdfdb") diff --git a/light9/rdfdb/patchsender.py b/light9/rdfdb/patchsender.py --- a/light9/rdfdb/patchsender.py +++ b/light9/rdfdb/patchsender.py @@ -3,25 +3,6 @@ import cyclone.httpclient from twisted.internet import defer log = logging.getLogger('syncedgraph') -def sendPatch(putUri, patch, **kw): - """ - kwargs will become extra attributes in the toplevel json object - """ - body = patch.makeJsonRepr(kw) - log.debug("send body: %r", body) - def ok(done): - if not str(done.code).startswith('2'): - raise ValueError("sendPatch request failed %s: %s" % (done.code, done.body)) - log.debug("sendPatch finished, response: %s" % done.body) - return done - - return cyclone.httpclient.fetch( - url=putUri, - method='PUT', - headers={'Content-Type': ['application/json']}, - postdata=body, - ).addCallback(ok) - class PatchSender(object): """ SyncedGraph may generate patches faster than we can send @@ -29,6 +10,13 @@ class PatchSender(object): they go the server """ def __init__(self, target, myUpdateResource): + """ + target is the URI we'll send patches to + + myUpdateResource is the URI for this sender of patches, which + maybe needs to be the actual requestable update URI for + sending updates back to us + """ self.target = target self.myUpdateResource = myUpdateResource self._patchesToSend = [] @@ -93,3 +81,23 @@ class PatchSender(object): log.error(e) self._continueSending() +def sendPatch(putUri, patch, **kw): + """ + PUT a patch as json to an http server. Returns deferred. + + kwargs will become extra attributes in the toplevel json object + """ + body = patch.makeJsonRepr(kw) + log.debug("send body: %r", body) + def ok(done): + if not str(done.code).startswith('2'): + raise ValueError("sendPatch request failed %s: %s" % (done.code, done.body)) + log.debug("sendPatch finished, response: %s" % done.body) + return done + + return cyclone.httpclient.fetch( + url=putUri, + method='PUT', + headers={'Content-Type': ['application/json']}, + postdata=body, + ).addCallback(ok) diff --git a/light9/rdfdb/syncedgraph.py b/light9/rdfdb/syncedgraph.py --- a/light9/rdfdb/syncedgraph.py +++ b/light9/rdfdb/syncedgraph.py @@ -59,7 +59,7 @@ class SyncedGraph(CurrentStateGraphApi, self.initiallySynced = defer.Deferred() _graph = self._graph = ConjunctiveGraph() - self._receiver = PatchReceiver(label, _graph, self.initiallySynced) + self._receiver = PatchReceiver(_graph, label, self.initiallySynced) self._sender = PatchSender('http://localhost:8051/patches', self._receiver.updateResource)