Skip to content

Multiple DynamicProviders not handled correctly #133

Open
@Synthetica9

Description

@Synthetica9

Description

Only one DynamicProvider is really supported, the second one is dispatched incorrectly.

To reproduce

Run the following server:

from p4p.server import Server, DynamicProvider
from p4p.server.thread import SharedPV
from p4p.nt import NTScalar

class DynHandler(object):
    def __init__(self, name):
        self.name = name
        self.pv = SharedPV(nt=NTScalar('d'), initial=0.0)

    def testChannel(self, name): # return True, False, or DynamicProvider.NotYet
        return name == self.name

    def makeChannel(self, name, peer):
        assert name == self.name
        return self.pv

providers = [
    DynamicProvider("foo", DynHandler("foo")),
    DynamicProvider("bar", DynHandler("bar")),
]
server = Server.forever(providers)

Then run pvget foo

Observed behaviour

bar is also called, raising an assertion error:

Unexpected
Traceback (most recent call last):
  File "/ics/tools/p4p/python3.8/linux-x86_64/p4p/server/__init__.py", line 238, in makeChannel
    return self._real.makeChannel(name, peer)
  File "/tmp/multi_p4p.py", line 14, in makeChannel
    assert name == self.name
AssertionError
TypeError: makeChannel("foo") must return SharedPV, not NoneType

Expected behaviour

Only foo channel is called.

Stopgap solution

class MergeHandler:
    def __init__(self, handlers):
        self.handlers = handlers

    def get_responsible(self, name):
        responsible = [
            handler for handler in self.handlers if handler.testChannel(name)
        ]
        if len(responsible) == 1:
            return responsible[0]

        elif len(responsible) == 0:
            return

        else:
            raise ValueError("More than one responsible handler~!")

    def testChannel(self, name):
        return self.get_responsible(name) is not None

    def makeChannel(self, name, peer):
        responsible = self.get_responsible(name)
        return responsible.makeChannel(name, peer)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions