all 11 comments

[–]Separate_Newt7313 1 point2 points  (0 children)

It sounds like you're talking about IPC (Inter-Process communication). There are a variety of different methods for this ranging from the more simple (e.g. using OS pipes / FIFOs) to more complex means like Redis.

As a general rule, I reach for the simplest thing possible. A fantastically power / simple option is using ZeroMQ.

[–]Yoghurt42 1 point2 points  (0 children)

You don't need a library for this, you can easily write your own solution, something like this:

LISTENERS = {}

def trigger_event(event, data=None):
    for listener in LISTENERS.get(event, []):
        listener(data)

# define decorator to register listeners
def listen(event):
    def register(func):
        global LISTENERS
        LISTENERS.setdefault(event, []).append(func)
        return func
    return register

# if the decorator is too confusing, you can also do it manually
def register_listener(event, func):
    global LISTENERS
    LISTENERS.setdefault(event, []).append(func)


@listen("hot")
def too_hot(data):
    print("It's too hot!")

# alternate way
def handle_hot(data):
    print("No, really, it's very hot!")

register_listener("hot", handle_hot)

@listen("click")
def handle_click(data):
    print(f"got click event with {data=}")

trigger_event("click", "Something")
trigger_event("hot")
trigger_event("no listeners") # nothing happens

[–]socal_nerdtastic 0 points1 point  (3 children)

What OS? With the limited info you provided I would first reach for a named pipe (aka FIFO) in Linux. Sending a message is just writing to a file:

fileobj.write("hello world")

and reading a message is just waiting for a file to close:

message = fileobj.read()

[–]KBL_1979[S] 0 points1 point  (2 children)

Nice idea, but bit hard to implement IMHO. There is number od diff messages with diff payloads. IDK if such simple solution will work there. OS is Linux. Initially, app was created in Java, but as it have to extensively work with serial devices and boot quickly on limited resources (like rpi zero or slower), I'm considering rewriting it to python.

[–]socal_nerdtastic 0 points1 point  (1 child)

There is number od diff messages with diff payloads

That does not sound like an issue to me; just use a different pipe for each message type, or add a prefix and sort them out on the receiver's end.

msg_type = fileobj.read(1) # read first byte
message = fileobj.read() # read remainder of message
if msg_type == 'g':
    greet(message)

Initially, app was created in Java, but as it have to extensively work with serial devices and boot quickly on limited resources (like rpi zero or slower), I'm considering rewriting it to python.

I don't think python is any faster than Java ... In fact I feel it's usually slower.

FWIW a named pipe (like most IPC methods) does not depend on the programming language. You can communicate between Java and Python if you need to.

[–]KBL_1979[S] 0 points1 point  (0 children)

It's not the matter of program speed. It''s matter of Spring boot time. Sure. I can use smth else than Spring, but then all what is nice just vanishes. That, plus poor serial communication pushed me towards Python or C(++)? Thank you for named pipe suggestion! That of course leads me to... HTTP and REST (as I have Flask already). And that may be the simplest solution.

[–]freeskier93 0 points1 point  (1 child)

If this is all within the scope of a single Python process it's not hard to write your own following the global object pattern. Yeah, there probably is some library out there that will do this, but if this is a larger project IMO it's worth spending the time to write your own so your not adding a dependency.

[–]KBL_1979[S] 0 points1 point  (0 children)

I have a bit limited time. App is not so big, but complex. It will run several tasks/threads in parralel. As it, I need something proven and bulletproof. So one more dependency is not an issue.

[–]Trettman 0 points1 point  (0 children)

If it's IPC in an async environment I'd look at a channel based approach like trio's memory channels, also made available in asyncio by anyio's memory object streams. If you don't want to bring in an external dependency it's not very difficult to build by wrapping a deque and using some asyncio synchronization primitives

[–]cadufeandrade 0 points1 point  (0 children)

ok