python-opcua icon indicating copy to clipboard operation
python-opcua copied to clipboard

Create server node from different process

Open Lukas1811 opened this issue 6 years ago • 7 comments

My program is running in multiple different processes, one of them is running the OPC UA server and a handler process got callbacks to functions to handle special events. I will instantiate multiple nodes on the running server, if one callback is triggered by the handler process. To this point all of that works flawless, I create the instantiate the node like this:

self.object = self.server.get_objects_node().add_object(self.namespace_index, self.name ,self.type_id)

The add_object function returns the created object but if I access the server with a client there is no new object (If I call it from the same process the object is created with out a problem). Has anyone had a similar problem and know how to solve it ?

Lukas1811 avatar Sep 03 '19 13:09 Lukas1811

Like I was getting at before, call instantiate() to create an instance of a custom object.

See example here: https://github.com/FreeOpcUa/python-opcua/blob/master/examples/server-instantiate-object.py

zerox1212 avatar Sep 03 '19 23:09 zerox1212

The add_object() function only calls the create_object() function which also use the instantiate() function, in the end there is no difference. I also tested it with the instantiate() function and it doesn't work.

def create_object(parent, nodeid, bname, objecttype=None):
    """
    create a child node object
    arguments are nodeid, browsename, [objecttype]
    or namespace index, name, [objecttype]
    if objectype is given (a NodeId) then the type node is instantiated inclusive its child nodes
    """
    nodeid, qname = _parse_nodeid_qname(nodeid, bname)
    if objecttype is not None:
        objecttype = node.Node(parent.server, objecttype)
        dname = ua.LocalizedText(qname.Name)
        nodes = instantiate(parent, objecttype, nodeid, bname=qname, dname=dname)[0]
        return nodes
    else:
        return node.Node(parent.server, _create_object(parent.server, parent.nodeid, nodeid, qname, ua.ObjectIds.BaseObjectType))

Lukas1811 avatar Sep 04 '19 08:09 Lukas1811

I do not think this library is well tested in a multiprocess environment. I don't know your application, but do you really need multiple processes for OPC UA?

I suppose the issue is related to a Python process having a copy of the main process memory and all nodes of the server being held in a dict. A standard dict can't be used across processes with out having a Manager() I think? At any rate, adapting your code to call add_object on the server process will be much easier than supporting multiprocessing in this case.

zerox1212 avatar Sep 04 '19 13:09 zerox1212

what do you mean by different processes? multiprocess module? threading? anyway the entire opcua server is in one thread and any client accessing it is also served in same thread. So unless you are doing sometthings strange it should work fine. and we donnot have enough info to help more

oroulet avatar Sep 04 '19 17:09 oroulet

I'm pretty sure he is handing python ua functions off to a process, that process will have a copy of the main process memory. When he calls add_object it's getting added to that processes' dict, not the dict in the server process. That is why a client can't see the object he created. The original process with the server is responding and his new object is in the dict of the other process.

zerox1212 avatar Sep 04 '19 23:09 zerox1212

@oroulet Yes im using multiprocessing to create the process

@zerox1212 I have also thought about that, I think threads wouldn't have this problem, only processes will have it due to there own memory, like you mentioned

Lukas1811 avatar Sep 05 '19 19:09 Lukas1811

I have tried to use multiprocessing and have the same issue , where it can't create a node on OPC server.

jigar88 avatar Apr 19 '21 14:04 jigar88