Skip to content

Instantly share code, notes, and snippets.

@wolf0403
Created July 23, 2014 15:15
Show Gist options
  • Save wolf0403/ef0fe2f4356c658330c8 to your computer and use it in GitHub Desktop.
Save wolf0403/ef0fe2f4356c658330c8 to your computer and use it in GitHub Desktop.
Simple "RPC" in Greenlet
import gevent
from gevent import Greenlet
from gevent.queue import Queue
from gevent.lock import BoundedSemaphore
class Worker(object):
def __init__(self, *a, **kw):
self._glet = Greenlet(self.run, *a, **kw)
self._q = Queue()
self._sem = BoundedSemaphore()
def start(self):
self._glet.start()
def run(self):
stack = []
while True:
o = self._q.get()
if isinstance(o, StopIteration):
break
elif isinstance(o, Queue):
rt = stack[0](*stack[1:])
o.put(rt)
stack = []
else:
stack.append(o)
def call(self, method, c=None, *args):
self._sem.acquire()
try:
if c is None:
c = Queue()
assert isinstance(c, Queue)
q = self._q
q.put(method)
for a in args:
q.put(a)
q.put(c)
finally:
self._sem.release()
def stop(self):
self._q.put(StopIteration())
class NPC(Worker):
def greetings(self, name):
return "Greetings! {}".format(name)
class Etcd(Worker):
def __init__(self):
super(Etcd, self).__init__()
self._data = {}
def get(self, key, defvalue):
return self._data.get(key, defvalue)
def set(self, key, value):
rt = self._data.get(key, None)
self._data[key] = value
return value if rt is None else rt
if __name__ == '__main__':
etcd = Etcd()
etcd.start()
devnull = Queue()
etcd.call(etcd.set, devnull, "Foo", "Value")
def run(etcd):
c = Queue()
etcd.call(etcd.get, c, "Foo", None)
print (c.get())
etcd.stop()
main = gevent.spawn(lambda:run(etcd))
gevent.joinall([main, etcd._glet])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment