commit 53ae6759f6655f0561976b54e77b32dc6d213108
parent a8ee942152ad43bebd79f8ce596c9ebdbaf4b994
Author: lash <dev@holbrook.no>
Date: Wed, 11 Feb 2026 14:52:28 +0000
Enable multiple commands in service
Diffstat:
3 files changed, 96 insertions(+), 24 deletions(-)
diff --git a/dummy/tests/handler.py b/dummy/tests/handler.py
@@ -16,18 +16,73 @@ logg = logging.getLogger()
testdir = os.path.realpath(os.path.dirname(__file__))
+def zero_handler(v):
+ logg.debug('zero handler arg 0x{}'.format(v.hex()))
+ return 0
+
+
+def create_handler():
+ handler = Handler()
+ handler.register(0, zero_handler)
+ return handler
+
+
class TestHandler(unittest.TestCase):
def setUp(self):
self.store = MemStore()
- self.handler = Handler()
def test_handler(self):
+ handler = create_handler()
b = b'\x00\x00\x00\x00'
- r = self.handler.scan(b)
+ r = handler.scan(b)
self.assertEqual(r, 0)
+ def test_handler_pair_invalid(self):
+ handler = create_handler()
+ b = b'\x00\x00\x00\x00\x09\x00\x00\x00'
+ r = handler.scan(b)
+ self.assertEqual(r, 0)
+ with self.assertRaises(ValueError):
+ handler.scan(b'')
+
+
+ def test_handler_twopass(self):
+ handler = create_handler()
+ b = b'\x00\x00\x00'
+ r = handler.scan(b)
+ self.assertEqual(r, 1)
+ b = b'\x00'
+ r = handler.scan(b)
+ self.assertEqual(r, 0)
+
+
+ def test_handler_twopass_pair(self):
+ handler = create_handler()
+ b = b'\x00\x00\x00\x00\x09\x00\x00'
+ r = handler.scan(b)
+ self.assertEqual(r, 0)
+ b = b'\x00'
+ r = handler.scan(b'')
+ self.assertEqual(r, 1)
+ with self.assertRaises(ValueError):
+ handler.scan(b'\x00')
+
+
+ def test_handler_twopass_pair(self):
+ handler = create_handler()
+ b = b'\x00\x00\x00\x00\x09\x00\x00'
+ r = handler.scan(b)
+ self.assertEqual(r, 0)
+ b = b'\x00'
+ r = handler.scan(b'')
+ self.assertEqual(r, 1)
+ with self.assertRaises(ValueError):
+ handler.scan(b'\x00')
+
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/dummy/usawa/runnable/server.py b/dummy/usawa/runnable/server.py
@@ -4,7 +4,6 @@ import argparse
from usawa import Ledger, Entry, EntryPart, DemoWallet, ACL, UnitIndex, load
from usawa.context import Context
-from usawa.store import LedgerStore
from usawa.service import Handler, SocketServer
from whee.valkey import ValkeyStore
@@ -34,10 +33,9 @@ def main():
ledger_tree = load(arg.ledger_xml_file)
uidx = UnitIndex.from_tree(ledger_tree)
ledger = Ledger.from_tree(ledger_tree, acl=acl)
+
db = ValkeyStore('')
- store = LedgerStore(db, ledger)
-
- srv = SocketServer(store)
+ srv = SocketServer(db, ledger, acl=acl)
#srv.start()
diff --git a/dummy/usawa/service.py b/dummy/usawa/service.py
@@ -1,24 +1,33 @@
import logging
import socket
+from usawa.store import LedgerStore
+
logg = logging.getLogger('handler')
class Handler:
+ cmd_len = 1
+ len_len = 3
+
def __init__(self):
self.cmd = None
self.buf = b''
self.c = 0
self.l = 0
+ self.r = None
self.state = 0
+ self.h = {}
+
+
+ def register(self, k, fn):
+ self.h[k] = fn
def scan(self, v):
- self.buf = v
- if len(v) == 0:
- return -1
- if self.cmd == None:
+ self.buf += v
+ if self.state == 0:
r = self.handle_cmd()
if r > 0:
return r
@@ -26,9 +35,7 @@ class Handler:
return False
if self.handle_collect() > 0:
return False
- if self.cmd == 0:
- return self.handle_getlastserial()
- raise ValueError()
+ return self.handle()
def handle_cmd(self):
@@ -36,6 +43,7 @@ class Handler:
self.c = 1
self.l = -1
self.state = 1
+ self.r = None
return self.handle_len()
@@ -45,39 +53,53 @@ class Handler:
def handle_len(self):
+ if self.state != 1:
+ return -1
(l, v) = self.__remainder()
if l == 0:
return 0
if l < 3:
return 3 - l
+ v = self.buf[1:4]
self.l = int.from_bytes(v, byteorder='big')
self.c += 3
+ self.state = 2
+ logg.debug('cmd {} has len {}'.format(self.cmd, self.l))
return 0
def handle_collect(self):
+ if self.state != 2:
+ return -1
(l, v) = self.__remainder()
self.c += l
- c = self.c - 3
+ c = self.c - 4
if c >= l:
- self.r = True
- self.c = l + 3
+ c = self.l + 4
+ self.state = 3
+ self.r = self.buf[4:c]
+ self.buf = self.buf[c:]
+ self.c = 0
c = l
logg.debug('have cmd {} len {} arg {}'.format(self.cmd, self.l, self.buf[3:self.c].hex()))
return l - c
- def handle_getlastserial(self):
- logg.debug('would get last serial')
+ def handle(self):
self.state = 0
- return 0
+ fn = self.h.get(self.cmd)
+ if fn == None:
+ raise ValueError()
+ logg.debug('handling cmd {} arg 0x{} rest buffer 0x{}'.format(self.cmd, self.r.hex(), self.buf.hex()))
+ return fn(self.r)
class SocketServer:
- def __init__(self, store):
+ def __init__(self, db, ledger, acl=None):
self.scks = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.store = store
+ self.store = LedgerStore(db, ledger)
+ self.acl = acl
def start(self):
@@ -107,6 +129,3 @@ class SocketServer:
parse(bytes(data))
data.append(v)
logg.debug('read {}: {}'.format(len(b), b.hex()))
-
-
-