1

I have a class instance that I want to use in multiple files:

from .services import ClientService
from flask import Flask

app = Flask(__name__)
client = ClientService() # <-- this instance

from . import scheduler

The class itself:

class ClientService(object):
    def __init__(self):
        self.processing_demos = False
        self.demos_to_be_processed = []

    . . . .

    def push_demos(self, demo_list):
        self.processing_demos = True
        for demo in demo_list[::-1]:
            self.demos_to_be_processed.append(demo)

    def update(self):
        . . . .

I import it in two places, one runs the update method in a while loop and another one is in an apscheduler job that runs every 30 seconds.

from multiprocessing import Process, Value
from . import app, client
import time

def client_update_loop():
    while True:
        time.sleep(0.01)
        client.update() # <-- use here

if __name__ == "__main__":
    proc = Process(target=client_update_loop, args=())
    proc.start()  
    app.run(debug=True, use_reloader=False)
    proc.join()
from . import client

. . . .

client.push_demos(request_demos_list) # <-- use here

The problem I run into is that the client instance in the first file is different from the one in the second file. I assume it happens because it runs client = ClientService() when importing twice which creates two separate objects. I tried checking whether the client object was already created using env variables but it didn't help. I also tried moving the initialization to a different file but it ran into the same problem. At this point I'm out of ideas on how to go around this. I would like some suggestions on how to go around this (perhaps I need to restructure my modules in a different way).

Edit: After reading the comments I understood the actual problem (when I start a new process, it just copies objects as they are which results in two unsynced objects) and decided to put my update loop in asyncio rather than a different process:

async def client_update_loop():
    while True:
        time.sleep(0.01)
        client.update()
. . . .
asyncio.run(client_update_loop())

That way it runs flask and my update loop in parallel while using the same client instance.

  • 1
    You are using a *subprocess*, i.e. you are working with *two independent Python prodcesses*, they will not share state. – juanpa.arrivillaga Nov 04 '21 at 22:05
  • This has *nothing* to do with imports, importing never magically re-instantiates an object. An import *intitalizes a module*, or simply accesses an already initialized module from a cache, and then modifies the namespace in a way particular to the exact syntax you used. – juanpa.arrivillaga Nov 04 '21 at 22:06
  • Oh, didn't know this. Thanks for the info, will look into it. – Yaroslav Biloshytskyi Nov 04 '21 at 22:09
  • Relevant question: https://stackoverflow.com/questions/3671666/sharing-a-complex-object-between-processes – Oli Nov 05 '21 at 23:40

0 Answers0