Routing ideas
This commit is contained in:
parent
2063a6ea9c
commit
34aaaa4ccb
8
phasmplatform/common/router.py
Normal file
8
phasmplatform/common/router.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
class BaseRouter:
|
||||||
|
def post_message(self, namespace: bytes, topic: bytes, kind: bytes, body: bytes) -> None:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class StdOutRouter(BaseRouter):
|
||||||
|
def post_message(self, namespace: bytes, topic: bytes, kind: bytes, body: bytes) -> None:
|
||||||
|
print(f'{namespace.decode()}: {topic.decode()}: {kind.decode()}: {body.decode()}')
|
||||||
@ -1,8 +1,10 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from phasmplatform.common.config import from_toml
|
from phasmplatform.common.config import from_toml
|
||||||
|
from phasmplatform.common.router import StdOutRouter
|
||||||
|
|
||||||
from .runner import run_once
|
from .runners.base import BaseRunner
|
||||||
|
from .runners.wasmtime import WasmTimeRunner
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
@ -11,8 +13,19 @@ def main() -> int:
|
|||||||
|
|
||||||
del config
|
del config
|
||||||
|
|
||||||
|
stdout_router = StdOutRouter()
|
||||||
|
|
||||||
|
foo: BaseRunner
|
||||||
|
|
||||||
with open('/home/johan/projects/idea/phasm/examples/crc32.wasm', 'rb') as fil:
|
with open('/home/johan/projects/idea/phasm/examples/crc32.wasm', 'rb') as fil:
|
||||||
run_once(fil.read())
|
foo = WasmTimeRunner(stdout_router, fil.read())
|
||||||
|
|
||||||
|
namespace = b'test-namespace'
|
||||||
|
topic = b'test-topic'
|
||||||
|
kind = b'test-kind'
|
||||||
|
body = b'test-body'
|
||||||
|
|
||||||
|
foo.handle_message(namespace, topic, kind, body)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|||||||
@ -3,11 +3,22 @@ import wasm3 # type: ignore
|
|||||||
from phasmplatform.common.exceptions import PhashPlatformNonIntMainReturnError
|
from phasmplatform.common.exceptions import PhashPlatformNonIntMainReturnError
|
||||||
|
|
||||||
|
|
||||||
def run_once(wasm_bin: bytes) -> int:
|
def post_message(namespace: int, topic: int, kind: int, body: int) -> None:
|
||||||
|
print('namespace', namespace)
|
||||||
|
print('topic', topic)
|
||||||
|
print('kind', kind)
|
||||||
|
print('body', body)
|
||||||
|
|
||||||
|
|
||||||
|
def run_once_wasm3(wasm_bin: bytes) -> int:
|
||||||
env = wasm3.Environment()
|
env = wasm3.Environment()
|
||||||
rtime = env.new_runtime(1024 * 1024)
|
rtime = env.new_runtime(1024 * 1024)
|
||||||
rtime.load(env.parse_module(wasm_bin))
|
|
||||||
result = rtime.find_function('main')()
|
mod = env.parse_module(wasm_bin)
|
||||||
|
mod.link_function('imports', 'post_message', post_message)
|
||||||
|
|
||||||
|
rtime.load(mod)
|
||||||
|
result = rtime.find_function('handle_message')()
|
||||||
if result is None:
|
if result is None:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|||||||
0
phasmplatform/worker/runners/__init__.py
Normal file
0
phasmplatform/worker/runners/__init__.py
Normal file
33
phasmplatform/worker/runners/base.py
Normal file
33
phasmplatform/worker/runners/base.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
from phasmplatform.common.router import BaseRouter
|
||||||
|
|
||||||
|
|
||||||
|
class BaseRunner:
|
||||||
|
__slots__ = ('router', )
|
||||||
|
|
||||||
|
router: BaseRouter
|
||||||
|
|
||||||
|
def __init__(self, router: BaseRouter) -> None:
|
||||||
|
self.router = router
|
||||||
|
|
||||||
|
def alloc_bytes(self, data: bytes) -> int:
|
||||||
|
"""
|
||||||
|
Calls upon stdlib.types.__alloc_bytes__ to allocate a bytes object
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def read_bytes(self, ptr: int) -> bytes:
|
||||||
|
"""
|
||||||
|
Reads a byte object allocated by stdlib.types.__alloc_bytes__
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def handle_message(self, namespace: bytes, topic: bytes, kind: bytes, body: bytes) -> None:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def post_message(self, namespace_ptr: int, topic_ptr: int, kind_ptr: int, body_ptr: int) -> None:
|
||||||
|
namespace = self.read_bytes(namespace_ptr)
|
||||||
|
topic = self.read_bytes(topic_ptr)
|
||||||
|
kind = self.read_bytes(kind_ptr)
|
||||||
|
body = self.read_bytes(body_ptr)
|
||||||
|
|
||||||
|
self.router.post_message(namespace, topic, kind, body)
|
||||||
77
phasmplatform/worker/runners/wasmtime.py
Normal file
77
phasmplatform/worker/runners/wasmtime.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import ctypes
|
||||||
|
import struct
|
||||||
|
|
||||||
|
import wasmtime
|
||||||
|
|
||||||
|
from phasmplatform.common.router import BaseRouter
|
||||||
|
from .base import BaseRunner
|
||||||
|
|
||||||
|
|
||||||
|
class WasmTimeRunner(BaseRunner):
|
||||||
|
__slots__ = ('store', 'module', 'instance', 'exports')
|
||||||
|
|
||||||
|
def __init__(self, router: BaseRouter, wasm_bin: bytes) -> None:
|
||||||
|
super().__init__(router)
|
||||||
|
|
||||||
|
self.store = wasmtime.Store()
|
||||||
|
|
||||||
|
post_message_bind = wasmtime.Func(self.store, wasmtime.FuncType([
|
||||||
|
wasmtime.ValType.i32(),
|
||||||
|
wasmtime.ValType.i32(),
|
||||||
|
wasmtime.ValType.i32(),
|
||||||
|
wasmtime.ValType.i32(),
|
||||||
|
], []), self.post_message)
|
||||||
|
|
||||||
|
self.module = wasmtime.Module(self.store.engine, wasm_bin)
|
||||||
|
self.instance = wasmtime.Instance(self.store, self.module, [
|
||||||
|
post_message_bind,
|
||||||
|
])
|
||||||
|
|
||||||
|
self.exports = self.instance.exports(self.store)
|
||||||
|
|
||||||
|
def alloc_bytes(self, data: bytes) -> int:
|
||||||
|
alloc_bytes = self.exports['stdlib.types.__alloc_bytes__']
|
||||||
|
assert isinstance(alloc_bytes, wasmtime.Func)
|
||||||
|
ptr = alloc_bytes(self.store, len(data))
|
||||||
|
assert isinstance(ptr, int) # type hint
|
||||||
|
|
||||||
|
memory = self.exports['memory']
|
||||||
|
assert isinstance(memory, wasmtime.Memory) # type hint
|
||||||
|
|
||||||
|
data_ptr = memory.data_ptr(self.store)
|
||||||
|
data_len = memory.data_len(self.store)
|
||||||
|
|
||||||
|
idx = ptr + 8 # This is the header from alloc plus the header from __alloc_bytes__
|
||||||
|
for byt in data:
|
||||||
|
assert idx < data_len
|
||||||
|
data_ptr[idx] = ctypes.c_ubyte(byt)
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
return ptr
|
||||||
|
|
||||||
|
def read_bytes(self, ptr: int) -> bytes:
|
||||||
|
memory = self.exports['memory']
|
||||||
|
assert isinstance(memory, wasmtime.Memory) # type hint
|
||||||
|
|
||||||
|
data_ptr = memory.data_ptr(self.store)
|
||||||
|
data_len = memory.data_len(self.store)
|
||||||
|
|
||||||
|
raw = ctypes.string_at(data_ptr, data_len)
|
||||||
|
|
||||||
|
ptr = ptr + 4 # This is the header from alloc
|
||||||
|
|
||||||
|
print('raw[ptr:ptr + 4]', raw[ptr:ptr + 4])
|
||||||
|
length = struct.unpack('<I', raw[ptr:ptr + 4])
|
||||||
|
print('length', length)
|
||||||
|
|
||||||
|
return b'?'
|
||||||
|
|
||||||
|
def handle_message(self, namespace: bytes, topic: bytes, kind: bytes, body: bytes) -> None:
|
||||||
|
namespace_ptr = self.alloc_bytes(namespace)
|
||||||
|
topic_ptr = self.alloc_bytes(topic)
|
||||||
|
kind_ptr = self.alloc_bytes(kind)
|
||||||
|
body_ptr = self.alloc_bytes(body)
|
||||||
|
|
||||||
|
handle_message = self.exports['handle_message']
|
||||||
|
assert isinstance(handle_message, wasmtime.Func)
|
||||||
|
handle_message(self.store, namespace_ptr, topic_ptr, kind_ptr, body_ptr)
|
||||||
@ -1,3 +1,4 @@
|
|||||||
pywasm3==0.5.0
|
pywasm3==0.5.0
|
||||||
redis==4.5.4
|
redis==4.5.4
|
||||||
tomli==2.0.1 ; python_version < '3.11'
|
tomli==2.0.1 ; python_version < '3.11'
|
||||||
|
wasmtime==7.0.0
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user