Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve multiprocessing and concurrency #33

Closed
operand opened this issue Jun 16, 2023 · 9 comments
Closed

Improve multiprocessing and concurrency #33

operand opened this issue Jun 16, 2023 · 9 comments
Labels
enhancement New feature or request

Comments

@operand
Copy link
Owner

operand commented Jun 16, 2023

This issue is to discuss and track work on concurrency related improvements. v1.4.0 just recently added multiprocessing support, but there are more improvements that could be made.


Another multiprocessing improvement to explore would be to allow parallel processing of messages by individual agents. Currently they must complete processing of a message one at a time. See #95 for an example implementation from @wwj718.

@operand operand added the enhancement New feature or request label Jun 16, 2023
@operand operand changed the title Consider alternative multiprocessing approaches Improve multiprocessing to avoid the python GIL Jun 17, 2023
@operand operand self-assigned this Jun 17, 2023
@operand operand changed the title Improve multiprocessing to avoid the python GIL Improve multiprocessing Jun 20, 2023
@operand operand removed their assignment Jul 8, 2023
@operand operand changed the title Improve multiprocessing Multiprocessing Space type Jul 19, 2023
@operand operand changed the title Multiprocessing Space type Improve multiprocessing Jul 19, 2023
@hidaris
Copy link

hidaris commented Aug 3, 2023

I noticed that the topic of actions being currently executed in a blocking manner was discussed in #95. To avoid disrupting your context, I'm noting down my thoughts here.

If we build a perception-action feedback loop in the agent through actions, a situation might occur where the agent, while executing a 'move' action, hears or observes other events from the environment and may stop its current movement. However, in the current blocking scenario, such a case may not be easy to construct.

This case might not be very typical, and blocking has its uses in many situations. Perhaps we could refer to the approach of pyee to provide both blocking and non-blocking spaces.

@operand
Copy link
Owner Author

operand commented Aug 3, 2023

This is a good point. I think that makes the case for allowing both.

@wwj718
Copy link
Contributor

wwj718 commented Aug 3, 2023

If we build a perception-action feedback loop in the agent through actions, a situation might occur where the agent, while executing a 'move' action, hears or observes other events from the environment and may stop its current movement. However, in the current blocking scenario, such a case may not be easy to construct.

@hidaris It may not be difficult to implement the perception-action feedback loop in the current synchronization mechanism. In the implementation of SyncAgent, the message processing mechanism is parallel. When the action is blocked, a new message can enter. If the new message needs to interrupt the previous blocking action (implemented as future), any running future can be obtained through self._futures, and it can be canceled.

perception-action feedback may be better suited to be implemented as an asynchronous Agent.

@operand operand self-assigned this Aug 8, 2023
@operand
Copy link
Owner Author

operand commented Aug 9, 2023

I just merged 1.3.0 and I wanted to add here that I was able to abstract out the threading implementation to a single class.

https://github.com/operand/agency/blob/main/agency/processors/native_thread_processor.py

This should hopefully make it simple to support more multi-processing types like green threads and the multiprocessing module.

This doesn't address the issue of serial "one-at-a-time" processing on the agent, but it could be the start of how we abstract that as well.

@operand
Copy link
Owner Author

operand commented Aug 23, 2023

Just wanted to note here that I'm working through the update right now that will bring multiprocessing support. I think I need a couple few more days still but it's coming soon.

@operand
Copy link
Owner Author

operand commented Aug 30, 2023

This has been taking longer than I thought. It's still in progress and it's close but there are still some issues to work out.

There's currently an issue with the Gradio app for example, which has been tricky and forcing me to refactor some more. I just wanted to give another update since this is taking longer than expected.

@operand
Copy link
Owner Author

operand commented Sep 7, 2023

Alright this ended up being a larger change than I thought but I just released 1.4.0 with multiprocessing and it addresses some of what we discussed here.

In this update, I changed it so that actions are processed immediately and in parallel using threads, rather than serially (one at a time) as we discussed above.

The only issue with the implementation is that it uses threads. I didn't go so far as to spawn processes for each action (only each agent). So action processing per-agent is not yet fully parallel, only "concurrent".

Another possibility after this update is to introduce a cancel method of some kind to achieve the real-time control characteristics that was brought up.

I'm going to leave this discussion open for now incase we run into issues with this update, or want to discuss further improvements regarding concurrency.

@operand operand changed the title Improve multiprocessing Improve multiprocessing and concurrency Sep 7, 2023
@operand operand removed their assignment Sep 9, 2023
@hidaris
Copy link

hidaris commented Sep 10, 2023

Awesome, I'll read the updated documentation now. 👍

@operand
Copy link
Owner Author

operand commented Sep 26, 2023

I'm happy to say that I think this issue can be closed and that the concurrency and multiprocessing picture is pretty good now with 1.6.

And the sub-topic that we mentioned here regarding serial vs parallel processing is essentially supported since 1.4. In that version I changed it to where incoming actions spawn a thread immediately. Though this is subject to the GIL unfortunately, the logic is there, and can be taken advantage of if an action sleep()s or uses IO. What's not supported is making this behavior optional, but I think that's okay for now.

Pre-empting or canceling an action is also possible if you implement it using some form of loop that can be stopped. So the basic building blocks for a real-time system are there I believe. When/if we decide we need more direct support for those kinds of use cases, we can work on it then.

@operand operand closed this as completed Sep 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants