BarbicanInference / brick-one

A communal physical operating system, first prototype using O'doyle Rules
Other
0 stars 2 forks source link

Using core.async to create channels between the websocket handler and… #1

Closed interstar closed 5 months ago

interstar commented 5 months ago

… the inference engine. We post messages from websocket handler to engine on global *engine-inqueue and pass a temporary return channel for the engine to reply to us

berkan commented 5 months ago

hi phil, thanks for updating the readme.

i find myself again wanting to stay away from the server/client terminology, and adopt an agent-/peer-based semantics.

i feel the latter offers a much richer and open-ended way of thinking about where we want to be.

i don't even see the current implementation as having a server and client. these different agents/actors/peers offer services, but not in a server/client architecture. one provides a database, another a certain type of bi-directional connection (ie one input and one output channel, with a websocket interface).

in the next iterations, there will be other agents offering other databases and types of connection.

i had suggested using websockets partly because of the weaker association with server/client semantics (compared to http, say).

if i knew of a p2p networking stack for clojure/jvm (such as the mature holepunchto/hyperswarm: A distributed networking stack for connecting peers for javascript), i would have suggested we start with that straight-away.

what do you think?

update: see Exploring p2p solutions available to Clojure / on the JVM · Issue #2 · BarbicanInference/brick-one

interstar commented 5 months ago

Sure. Feel free to change terminology. We don't have to call this a server if you don't want to.

But I know we have a disagreement about this and I think it does reflect some rival architectural intuitions we need to get straight.

I think the use of a rules engine to do all the state manipulation in the system de facto implies an architecture where the rules engine has to sit in the centre and be given all the facts.

Otherwise the state in the system isn't just in the blackboard / rules engine but has to be spread through agents and their various ad hoc mechanisms that maintain and work on it.

Think of it like this. Suppose we wanted to be able to snapshot the state of a running system to be able to return to at some point in the future. Do we want to build a system where to do this, all we would have to do is save the current contents of the rules engine? Or do we want to build a system which is so distributed that we'd need to ask every agent connected to it to save its fragment of the state?

I'm not advocating for one or the other. Either is fine. I'm just saying that when we decide the architecture, the answer can't be "both" or "we don't know". We have to decide.

Either all the state is "on the blackboard" / in the rules engine. Or it isn't.

If it is, then there's no harm in accepting the engine is the centre or server of the system.

If it isn't, that's fine, but it means all the state transitions can't be calculated by a rules engine, because not all the state will be visible to that rules engine.

Maybe there are multiple agents with multiple engines and collections of rules and facts. But then the coordination between them, and state evolution is no longer just through firing rules.

Take the simplest example I can think of.

A box moves to the right with time. It's X coordinate proportional to the timer.

If all this information is centralised in a single rule engine, it's exactly like the examples we've played with. There's a rule for moving the box. The rules clearly express that when the timer changes the box X coordinate updates based on the new value.

Let's now imagine a system where there is a timer agent and a box agent that don't coordinate through a shared central rule engine but horizontally through web sockets.

Where is the information that this box needs to pay attention to that timer actually stored? How is the position of the box updated?

It's unlikely to be in the timer agent. So let's suppose it's in the box agent. But even if the box agent is using is own private rules engine, it won't automatically know when the timer has updated itself. Because that value is coming from somewhere outside itself.

So now the box agent needs to be regularly polling the timer agent to get the up-to-date value of the timer, which it then uses to update the position of its box. But the code which does that polling is not itself expressed as a rule in the local rule engine. It's outside the engine. What if the fact that this box depends on that timer itself has to change? Again this needs more changes to code that is not rules in an engine but represented elsewhere.

Obviously we don't really want the RoomOS users/ programmers to have to faff around writing custom web socket code every time they define communications between a agents.

So we might think that what we want is a rules engine which is transparently distributed over multiple agents. From the RoomOS programmer's perspective it looks like one monolithic fact and rule collection but implementationally it happens to be multisharded. But if users can't see this at all, then it doesn't really matter to them. It may as well be a centralised server until such time as we find it didn't scale to the complexity we need.

So what does it mean for the users / RoomOS programmers to need to think about it as a multiagent system?

If a user points a piece of paper with a box on it and code for "move this box according to that timer" next to a piece of paper with a timer on it, we automatically create a connection between those two entities in our system. But that could mean posting these new facts and rules into the same rules engine. Or creating two objects on different threads that communicate over internal channels. Or spinning up two OS processes with two entirely different programs that communicate over websockets.

We have to decide which of these sorts of things we want as our basic architecture for a RoomOS. What are the pros and cons of each etc.

Are you coming to lunch with me and Oli today?

On Tue, 23 Jan 2024, 5:26 pm Berkan Eskikaya, @.***> wrote:

hi phil, thanks for updating the readme.

i find myself again wanting to stay away from the server/client terminology, and adopt an agent-based semantics.

i feel the latter offers a much richer and open-ended way of thinking about where we want to be.

i don't even see the current implementation as having a server and client. these different agents/actors offer services, but not in a server/client architecture. one provides a database, another a certain type of bi-directional connection (ie one input and one output channel).

in the next iterations, there will be other agents offering other databases and types of connection.

i had suggested using websockets partly because of the weaker association with server/client semantics (compared to http, say).

if i knew of a p2p networking stack for clojure/jvm (such as the mature holepunchto/hyperswarm: A distributed networking stack for connecting peers. https://github.com/holepunchto/hyperswarm for javascript), i would have suggested we start with that straight-away.

what do you think?

— Reply to this email directly, view it on GitHub https://github.com/BarbicanInference/brick-one/pull/1#issuecomment-1906565459, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAWG5XPIFAWJVSXL3HWGNLYP7XFDAVCNFSM6AAAAABCE72AVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMBWGU3DKNBVHE . You are receiving this because you authored the thread.Message ID: @.***>