Compare commits
2 commits
9ee4dd73aa
...
bc12966b70
| Author | SHA1 | Date | |
|---|---|---|---|
| bc12966b70 | |||
| 334df9afbd |
5 changed files with 61 additions and 33 deletions
|
|
@ -13,14 +13,12 @@ from scopes.core.message import Message
|
||||||
from scopes import util
|
from scopes import util
|
||||||
from scopes.util import keywords as k, Symbol, Symbols
|
from scopes.util import keywords as k, Symbol, Symbols
|
||||||
|
|
||||||
# keywords (domains, actions, categories, stages):
|
# keywords (domains, actions, classes, stages, data keys):
|
||||||
k('csys', 'env',
|
k('csys ctl env',
|
||||||
'connect', 'create', 'created', 'data', 'default', 'value',
|
'connect create created data default query set value',
|
||||||
'c00', 'e00', 's00',
|
'c00 e00 s00 rcvr op',
|
||||||
'initial', 'active', 'retired')
|
'initial active retired',
|
||||||
|
'address pred succ')
|
||||||
dom = util.Symbols('dom')('csys', 'env')
|
|
||||||
cat = util.Symbols('cat')('c00', 'e00', 's00')
|
|
||||||
|
|
||||||
type Mailbox = asyncio.Queue
|
type Mailbox = asyncio.Queue
|
||||||
type Categ = tuple[Symbol, Symbol]
|
type Categ = tuple[Symbol, Symbol]
|
||||||
|
|
@ -54,14 +52,14 @@ def synapse(rcvr: Mailbox, op: SynOp = lambda x: x) -> Syn:
|
||||||
env_dummy: Mailbox = asyncio.Queue()
|
env_dummy: Mailbox = asyncio.Queue()
|
||||||
|
|
||||||
def notify() -> Handler:
|
def notify() -> Handler:
|
||||||
async def handle(msg, scope) -> None:
|
async def handle(msg: Message, scope: Scope) -> None:
|
||||||
await scope.environ.put(msg)
|
await scope.environ.put(msg)
|
||||||
return handle
|
return handle
|
||||||
|
|
||||||
def gen_proc(actions: Actions, default: Handlers = notify(),
|
def gen_proc(actions: Actions, default: Handlers = notify(),
|
||||||
prepare: Handlers = None, finalize: Handlers = None) -> Proc:
|
prepare: Handlers = None, finalize: Handlers = None) -> Proc:
|
||||||
async def proc(msg: Message, scope: Scope) -> Scope:
|
async def proc(msg: Message, scope: Scope) -> Scope:
|
||||||
acts = actions.get(msg.head.action, actions.get(k.default, default))
|
acts = actions.get(msg.action, actions.get(k.default, default))
|
||||||
acts = util.flatten(prepare, acts, finalize, ignore_none=True)
|
acts = util.flatten(prepare, acts, finalize, ignore_none=True)
|
||||||
for act in acts:
|
for act in acts:
|
||||||
msg = await act(msg, scope)
|
msg = await act(msg, scope)
|
||||||
|
|
@ -87,7 +85,7 @@ def gen_program(spec: ProgramSpec, default: Proc = gen_proc({})) -> Program:
|
||||||
class Scope:
|
class Scope:
|
||||||
|
|
||||||
value: Any = 0
|
value: Any = 0
|
||||||
categ: Categ = (k.csys, cat.c00)
|
categ: Categ = (k.csys, k.c00)
|
||||||
stage: Symbol = k.initial
|
stage: Symbol = k.initial
|
||||||
proc: Proc = field(init=False)
|
proc: Proc = field(init=False)
|
||||||
program: Program = gen_program({})
|
program: Program = gen_program({})
|
||||||
|
|
@ -101,7 +99,7 @@ class Scope:
|
||||||
self.proc = self.program(self)
|
self.proc = self.program(self)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def create_scope(env: Mailbox, cat: Categ = (k.csys, cat.c00), **kw) -> Scope:
|
def create_scope(env: Mailbox, cat: Categ = (k.csys, k.c00), **kw) -> Scope:
|
||||||
return Scope(environ=env, categ=cat, **kw)
|
return Scope(environ=env, categ=cat, **kw)
|
||||||
|
|
||||||
def clone_scope(scope: Scope, **kw) -> Scope:
|
def clone_scope(scope: Scope, **kw) -> Scope:
|
||||||
|
|
@ -109,7 +107,7 @@ def clone_scope(scope: Scope, **kw) -> Scope:
|
||||||
categ = kw.get('categ', scope.categ)
|
categ = kw.get('categ', scope.categ)
|
||||||
stage = kw.get('stage', k.initial)
|
stage = kw.get('stage', k.initial)
|
||||||
return Scope(environ=scope.environ, value=value, categ=categ, stage=stage,
|
return Scope(environ=scope.environ, value=value, categ=categ, stage=stage,
|
||||||
program=scope.program, syns=[], **kw)
|
program=scope.program, syns=[])
|
||||||
|
|
||||||
async def create_zero(env: Mailbox) -> Mailbox:
|
async def create_zero(env: Mailbox) -> Mailbox:
|
||||||
scope = create_scope(env, program=gen_program({}, default=std_proc()))
|
scope = create_scope(env, program=gen_program({}, default=std_proc()))
|
||||||
|
|
@ -120,27 +118,33 @@ async def create_zero(env: Mailbox) -> Mailbox:
|
||||||
# predefined action handlers and Action sets
|
# predefined action handlers and Action sets
|
||||||
|
|
||||||
def forward() -> Handler:
|
def forward() -> Handler:
|
||||||
async def handle(msg, scope) -> None:
|
async def handle(msg: Message, scope: Scope) -> None:
|
||||||
for syn in scope.syns:
|
for syn in scope.syns:
|
||||||
await syn(msg)
|
await syn(msg)
|
||||||
return handle
|
return handle
|
||||||
|
|
||||||
def value_add() -> Handler:
|
def value_add() -> Handler:
|
||||||
async def handle(msg, scope) -> tuple[Message, Scope]:
|
async def handle(msg: Message, scope: Scope) -> tuple[Message, Scope]:
|
||||||
return msg, scope
|
return msg, scope
|
||||||
return handle
|
return handle
|
||||||
|
|
||||||
def create() -> Handler:
|
def create() -> Handler:
|
||||||
async def handle(msg, scope) -> None:
|
async def handle(msg: Message, scope: Scope) -> None:
|
||||||
new = neuron(clone_scope(scope, **msg.data))
|
new = neuron(clone_scope(scope, **msg.data))
|
||||||
await notify_created(msg, new, scope)
|
await notify_created(msg, new, scope)
|
||||||
|
conn = msg.data.get(k.connect)
|
||||||
|
return handle
|
||||||
|
|
||||||
|
def connect() -> Handler:
|
||||||
|
async def handle(msg: Message, scope: Scope) -> None:
|
||||||
return None
|
return None
|
||||||
return handle
|
return handle
|
||||||
|
|
||||||
def basic_actions() -> Actions:
|
def basic_actions() -> Actions:
|
||||||
acts: Actions = {
|
acts: Actions = {
|
||||||
k.value: value_add(),
|
k.value: value_add(),
|
||||||
k.create: create()
|
k.create: create(),
|
||||||
|
k.connect: connect()
|
||||||
}
|
}
|
||||||
return acts
|
return acts
|
||||||
|
|
||||||
|
|
@ -149,12 +153,13 @@ def basic_actions() -> Actions:
|
||||||
def std_proc(actions: Actions | None = None, finalize: Handler = forward(),
|
def std_proc(actions: Actions | None = None, finalize: Handler = forward(),
|
||||||
more: Actions = {}) -> Proc:
|
more: Actions = {}) -> Proc:
|
||||||
if actions is None:
|
if actions is None:
|
||||||
actions = basic_actions() | more
|
actions = basic_actions()
|
||||||
|
actions.update(more)
|
||||||
return gen_proc(actions, finalize=finalize)
|
return gen_proc(actions, finalize=finalize)
|
||||||
|
|
||||||
# helpers
|
# helpers
|
||||||
|
|
||||||
async def notify_created(msg: Message, new: Mailbox, scope: Scope) -> None:
|
async def notify_created(msg: Message, new: Mailbox, scope: Scope) -> None:
|
||||||
msg = Message(msg.head.domain, k.created, data=msg.data | {k.new: new})
|
msg = Message(msg.domain, k.created, data=msg.data | {k.new: new})
|
||||||
await scope.environ.put(msg)
|
await scope.environ.put(msg)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,22 @@ from scopes.core import actor
|
||||||
from scopes.core.message import Message
|
from scopes.core.message import Message
|
||||||
from scopes.util import keywords as k
|
from scopes.util import keywords as k
|
||||||
|
|
||||||
def create(meta_env: core.Mailbox) -> core.Mailbox:
|
def create_env(meta_env: core.Mailbox) -> core.Mailbox:
|
||||||
scope = core.create_scope(meta_env, (k.env, k.c00),
|
scope = core.create_scope(meta_env, (k.env, k.c00),
|
||||||
program=core.gen_program({}))
|
program=core.gen_program({}, default=env_proc()))
|
||||||
return core.neuron(scope)
|
return core.neuron(scope)
|
||||||
|
|
||||||
|
def env_proc() -> core.Proc:
|
||||||
|
return core.gen_proc(env_actions(), default=None, finalize=core.notify())
|
||||||
|
|
||||||
|
def handle_created() -> core.Handler:
|
||||||
|
async def handle(msg: Message, scope: core.Scope) -> Message:
|
||||||
|
return msg
|
||||||
|
return handle
|
||||||
|
|
||||||
|
def env_actions() -> core.Actions:
|
||||||
|
return {
|
||||||
|
k.created: handle_created(),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,14 @@ class Symbol(str):
|
||||||
|
|
||||||
class Symbols:
|
class Symbols:
|
||||||
|
|
||||||
def __init__(self, prefix=None):
|
def __init__(self, ns=None):
|
||||||
self.__prefix = prefix
|
self.__prefix = ns + '.' if ns else ''
|
||||||
|
|
||||||
def __call__(self, *ks):
|
def __call__(self, *keys):
|
||||||
prefix = self.__prefix + '.' if self.__prefix else ''
|
for segment in keys:
|
||||||
for k in ks:
|
for key in segment.split():
|
||||||
if not hasattr(self, k):
|
if not hasattr(self, key):
|
||||||
setattr(self, k, Symbol(prefix + k))
|
setattr(self, key, Symbol(self.__prefix + key))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __getattr__(self, k):
|
def __getattr__(self, k):
|
||||||
|
|
|
||||||
|
|
@ -67,12 +67,12 @@ async def meta_env(collector):
|
||||||
|
|
||||||
@pytest.mark.anyio
|
@pytest.mark.anyio
|
||||||
async def test_core(meta_env, collector):
|
async def test_core(meta_env, collector):
|
||||||
env = environ.create(meta_env)
|
env = environ.create_env(meta_env)
|
||||||
zero = await core.create_zero(env)
|
zero = await core.create_zero(env)
|
||||||
await env.put(Message(k.env, k.hello))
|
await env.put(Message(k.env, k.hello))
|
||||||
await zero.put(Message(k.csys, k.hello))
|
await zero.put(Message(k.csys, k.hello))
|
||||||
await zero.put(Message(k.csys, k.create))
|
await zero.put(Message(k.csys, k.create,
|
||||||
#data={k.connect: k.pred, k.address: (1, 1)}))
|
data={k.connect: k.pred, k.address: (1, 1)}))
|
||||||
await asyncio.sleep(0.01)
|
await asyncio.sleep(0.01)
|
||||||
assert len(collector) == 4
|
assert len(collector) == 4
|
||||||
assert collector[0].action is k.created
|
assert collector[0].action is k.created
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,24 @@
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from scopes.util import keywords as k, flatten
|
from scopes.util import keywords as k, flatten, Symbols
|
||||||
k('dummy', 'other', 'cd', 'new')
|
|
||||||
|
k('dummy other', 'cd', 'new', 'erp')
|
||||||
|
|
||||||
|
dom = Symbols('dom')('crm erp sys')
|
||||||
|
|
||||||
def test_keywords():
|
def test_keywords():
|
||||||
|
assert k.dummy == 'dummy'
|
||||||
|
assert k.dummy is not 'dummy'
|
||||||
assert k.dummy is k.dummy
|
assert k.dummy is k.dummy
|
||||||
assert k.dummy is not k.other
|
assert k.dummy is not k.other
|
||||||
assert getattr(k, "abcd"[-2:]) is k.cd
|
assert getattr(k, "abcd"[-2:]) is k.cd
|
||||||
assert k['dummy'] is k.dummy
|
assert k['dummy'] is k.dummy
|
||||||
assert k['new'] is k['new']
|
assert k['new'] is k['new']
|
||||||
|
assert dom.erp == 'dom.erp'
|
||||||
|
assert dom.erp is not 'dom.erp'
|
||||||
|
assert repr(dom.erp) == '<dom.erp>'
|
||||||
|
assert dom.erp != k.erp
|
||||||
|
|
||||||
def test_flatten():
|
def test_flatten():
|
||||||
lst = (1, (None, 2), (3, (4, 5)))
|
lst = (1, (None, 2), (3, (4, 5)))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue