I wanna make a process supervisor app.
It has two basic components: a control api service and the main supervisor service.
And I wanna roll it on a single-threaded model with async/await approach.
I can easily model the main sketch in python or any other PL with GC like this:
import asyncio
import random
class App:
def __init__(self):
self.api = ControlService(self)
self.supervisor = SupervisorService()
async def serve(self):
await asyncio.wait([
self.api.serve(),
self.supervisor.serve()
])
class ControlService:
def __init__(self, app):
self.app = app
async def serve(self):
while True:
print('[ControlService ] Waiting user request...')
cmd, arg = await simulate_user_request()
print("[ControlService ] Received user cmd: {}".format([cmd, arg]))
if cmd == "set":
self.app.supervisor.set_value(arg)
else:
pass
class SupervisorService:
def __init__(self):
self._value = 0
def set_value(self, value):
self._value = value
async def serve(self):
while True:
print('[SupervisorService] Business value: {}'.format(self._value))
await asyncio.sleep(1)
async def simulate_user_request():
await asyncio.sleep(2)
return "set", random.randint(0, 10)
if __name__ == '__main__':
app = App()
loop = asyncio.get_event_loop()
loop.run_until_complete(app.serve())
loop.close()
But with Rust I have problem:
If the control service and supervisor serve both serving, then the supervisor must be borrowed and be held in the async fn serve(self: &SupervisorService)
. So, The control service is impossible to mutate the supervisor service's parameter.
So, How can I solve the problem?
What's the best practice of making this kind of app in Rust?