Skip to content

Commit

Permalink
Merge pull request #400 from giodegas/master
Browse files Browse the repository at this point in the history
A simple basic asynchrounous service boilerplate example
  • Loading branch information
comrumino authored Aug 18, 2020
2 parents 3632c32 + 7d9ba8d commit ed6ae57
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
31 changes: 31 additions & 0 deletions demos/boilerplate/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generic RPyC service boiler plate

This service is ispired by the FileMonitor example.

It will monitor the file `/tmp/test.txt` to geenrate asynchrounous events that will be notified to the RPyC client.

run in one terminal:

python3 rpyc_server.py

run is a second terminal:

python3 rpyc_client.py

at the server console:

news client with /tmp/test.txt <bound method MyClient.on_event of <__main__.MyClient object at 0x7f40bd1e3070>>

then open a third terminal and give some commands like:

touch /tmp/test.txt

you should read from the client console:

file changed
old stat: os.stat_result(st_mode=33204, st_ino=1181245, st_dev=2053, st_nlink=1, st_uid=1000, st_gid=1000, st_size=0, st_atime=1596994889, st_mtime=1596994889, st_ctime=1596994889)
new stat: os.stat_result(st_mode=33204, st_ino=1181245, st_dev=2053, st_nlink=1, st_uid=1000, st_gid=1000, st_size=0, st_atime=1596995295, st_mtime=1596995295, st_ctime=1596995295)

then after 30s at the server console you see:

client closed.
28 changes: 28 additions & 0 deletions demos/boilerplate/rpyc_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import rpyc
from time import sleep


class MyClient(object):

def __init__(self):
self.conn = rpyc.connect("localhost", 18000)
self.bgsrv = rpyc.BgServingThread(self.conn)
self.root = self.conn.root
self.service = self.root.MyService("/tmp/test.txt", self.on_event) # create a filemon

def on_event(self, oldstat, newstat):
print("file changed")
print(" old stat: %s" % (oldstat,))
print(" new stat: %s" % (newstat,))

def close(self):
self.service.stop()
self.bgsrv.stop()
self.conn.close()


if __name__ == "__main__":

client = MyClient()
sleep(10)
client.close()
5 changes: 5 additions & 0 deletions demos/boilerplate/rpyc_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from rpyc.utils.server import ThreadedServer
from rpyc_service import MyServiceFactory

if __name__ == "__main__":
ThreadedServer(MyServiceFactory, port = 18000).start()
32 changes: 32 additions & 0 deletions demos/boilerplate/rpyc_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import rpyc
import os
from threading import Thread
import time


class MyServiceFactory(rpyc.Service):

class exposed_MyService(object): # exposing names is not limited to methods :)

def __init__(self, filename, callback, interval = 1):
print("news client with " + filename + " " + str(callback))
self.filename = filename
self.interval = interval
self.last_stat = None
self.callback = rpyc.async_(callback) # create an async callback
self.active = True
self.thread = Thread(target = self.work)
self.thread.start()

def exposed_stop(self): # this method has to be exposed too
self.active = False
self.thread.join()

def work(self):
while self.active:
stat = os.stat(self.filename)
if self.last_stat is not None and self.last_stat != stat:
self.callback(self.last_stat, stat) # notify the client of the change
self.last_stat = stat
time.sleep(self.interval)
print("client closed.")

0 comments on commit ed6ae57

Please sign in to comment.