-
Notifications
You must be signed in to change notification settings - Fork 9
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
Multiple messenger interface support #332
base: dev
Are you sure you want to change the base?
Changes from 5 commits
e4a2d61
97c54a8
738adff
8f96abb
2a280a5
087dfbf
f4c4eeb
3c02196
90037a2
d32691f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,11 +16,12 @@ | |
|
||
import asyncio | ||
import logging | ||
from typing import Union, List, Dict, Optional, Hashable, Callable | ||
from typing import Iterable, Union, List, Dict, Optional, Hashable, Callable | ||
from uuid import uuid4 | ||
|
||
from dff.context_storages import DBContextStorage | ||
from dff.script import Script, Context, ActorStage | ||
from dff.script import NodeLabel2Type, Message | ||
from dff.script import NodeLabel2Type, Message, DEFAULT_INTERFACE_ID | ||
from dff.utils.turn_caching import cache_clear | ||
|
||
from dff.messengers.common import MessengerInterface, CLIMessengerInterface | ||
|
@@ -62,7 +63,7 @@ class Pipeline: | |
- key: :py:class:`~dff.script.ActorStage` - Stage in which the handler is called. | ||
- value: List[Callable] - The list of called handlers for each stage. Defaults to an empty `dict`. | ||
|
||
:param messenger_interface: An `AbsMessagingInterface` instance for this pipeline. | ||
:param messenger_interfaces: An `AbsMessagingInterface` instance for this pipeline. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: fix docs |
||
:param context_storage: An :py:class:`~.DBContextStorage` instance for this pipeline or | ||
a dict to store dialog :py:class:`~.Context`. | ||
:param services: (required) A :py:data:`~.ServiceGroupBuilder` object, | ||
|
@@ -92,7 +93,7 @@ def __init__( | |
condition_handler: Optional[Callable] = None, | ||
verbose: bool = True, | ||
handlers: Optional[Dict[ActorStage, List[Callable]]] = None, | ||
messenger_interface: Optional[MessengerInterface] = None, | ||
messenger_interfaces: Optional[Union[MessengerInterface, Iterable[MessengerInterface], Dict[str, MessengerInterface]]] = None, | ||
context_storage: Optional[Union[DBContextStorage, Dict]] = None, | ||
before_handler: Optional[ExtraHandlerBuilder] = None, | ||
after_handler: Optional[ExtraHandlerBuilder] = None, | ||
|
@@ -101,7 +102,6 @@ def __init__( | |
parallelize_processing: bool = False, | ||
): | ||
self.actor: Actor = None | ||
self.messenger_interface = CLIMessengerInterface() if messenger_interface is None else messenger_interface | ||
self.context_storage = {} if context_storage is None else context_storage | ||
self._services_pipeline = ServiceGroup( | ||
components, | ||
|
@@ -110,6 +110,16 @@ def __init__( | |
timeout=timeout, | ||
) | ||
|
||
if messenger_interfaces is not None and not isinstance(messenger_interfaces, MessengerInterface): | ||
if isinstance(messenger_interfaces, Iterable): | ||
self.messenger_interfaces = {str(uuid4()): iface for iface in messenger_interfaces} | ||
elif isinstance(messenger_interfaces, Iterable): | ||
self.messenger_interfaces = messenger_interfaces | ||
else: | ||
raise RuntimeError(f"Unexpected type of 'messenger_interfaces': {type(messenger_interfaces)}") | ||
pseusys marked this conversation as resolved.
Show resolved
Hide resolved
|
||
else: | ||
self.messenger_interfaces = {DEFAULT_INTERFACE_ID: CLIMessengerInterface()} | ||
|
||
self._services_pipeline.name = "pipeline" | ||
self._services_pipeline.path = ".pipeline" | ||
actor_exists = finalize_service_group(self._services_pipeline, path=self._services_pipeline.path) | ||
|
@@ -188,7 +198,9 @@ def info_dict(self) -> dict: | |
""" | ||
return { | ||
"type": type(self).__name__, | ||
"messenger_interface": f"Instance of {type(self.messenger_interface).__name__}", | ||
"messenger_interfaces": { | ||
k: f"Instance of {type(v).__name__}" for k, v in self.messenger_interfaces.items() | ||
}, | ||
"context_storage": f"Instance of {type(self.context_storage).__name__}", | ||
"services": [self._services_pipeline.info_dict], | ||
} | ||
|
@@ -217,7 +229,7 @@ def from_script( | |
parallelize_processing: bool = False, | ||
handlers: Optional[Dict[ActorStage, List[Callable]]] = None, | ||
context_storage: Optional[Union[DBContextStorage, Dict]] = None, | ||
messenger_interface: Optional[MessengerInterface] = None, | ||
messenger_interfaces: Optional[Union[MessengerInterface, Iterable[MessengerInterface], Dict[str, MessengerInterface]]] = None, | ||
RLKRo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pre_services: Optional[List[Union[ServiceBuilder, ServiceGroupBuilder]]] = None, | ||
post_services: Optional[List[Union[ServiceBuilder, ServiceGroupBuilder]]] = None, | ||
) -> "Pipeline": | ||
|
@@ -249,7 +261,7 @@ def from_script( | |
|
||
:param context_storage: An :py:class:`~.DBContextStorage` instance for this pipeline | ||
or a dict to store dialog :py:class:`~.Context`. | ||
:param messenger_interface: An instance for this pipeline. | ||
:param messenger_interfaces: An instance for this pipeline. | ||
:param pre_services: List of :py:data:`~.ServiceBuilder` or | ||
:py:data:`~.ServiceGroupBuilder` that will be executed before Actor. | ||
:type pre_services: Optional[List[Union[ServiceBuilder, ServiceGroupBuilder]]] | ||
|
@@ -270,7 +282,7 @@ def from_script( | |
verbose=verbose, | ||
parallelize_processing=parallelize_processing, | ||
handlers=handlers, | ||
messenger_interface=messenger_interface, | ||
messenger_interfaces=messenger_interfaces, | ||
context_storage=context_storage, | ||
components=[*pre_services, ACTOR, *post_services], | ||
) | ||
|
@@ -369,7 +381,7 @@ def run(self): | |
This method can be both blocking and non-blocking. It depends on current `messenger_interface` nature. | ||
Message interfaces that run in a loop block current thread. | ||
""" | ||
asyncio.run(self.messenger_interface.connect(self._run_pipeline)) | ||
asyncio.run(asyncio.gather(*[iface.connect(self._run_pipeline, id) for id, iface in self.messenger_interfaces.items()])) | ||
|
||
def __call__( | ||
self, request: Message, ctx_id: Optional[Hashable] = None, update_ctx_misc: Optional[dict] = None | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -252,7 +252,7 @@ class ExtraHandlerRuntimeInfo(BaseModel): | |
PipelineBuilder: TypeAlias = TypedDict( | ||
"PipelineBuilder", | ||
{ | ||
"messenger_interface": NotRequired[Optional["MessengerInterface"]], | ||
"messenger_interfaces": NotRequired[Optional[Union["MessengerInterface", Iterable["MessengerInterface"], Dict[str, "MessengerInterface"]]]], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update this. |
||
"context_storage": NotRequired[Optional[Union[DBContextStorage, Dict]]], | ||
"components": ServiceGroupBuilder, | ||
"before_handler": NotRequired[Optional[ExtraHandlerBuilder]], | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
all, | ||
negation, | ||
has_last_labels, | ||
from_interface, | ||
true, | ||
false, | ||
agg, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should also add tests for launching pipeline with multiple http interfaces and running them at the same time on different ports. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why add this parameter when it is always
self.name
?