etm.wccoa.msa.base
Protocol-neutral part of MSA — everything that does not know the payload type.
Importing this package must work without WinCC OA.
Applications normally import etm.wccoa.msa.vrpc instead, which re-exports these names.
Package Contents
Classes
AsyncUnaryCall
|
Handle for a running unary RPC — waitable and awaitable at the same time. |
|---|---|
PayloadEncryptionMode
|
How a service treats encrypted payloads. |
Responder
|
Answers a call that the handler chose not to answer by returning (S3). |
ServerContext
|
What a handler can learn about the call it is serving. |
ServiceBase
|
Common state of a service: its name and its method table. |
ServiceContainer
|
Registers services, starts them, and shuts their threads down again. |
ServiceHostingReplica
|
Which half of a redundant system hosts the service. |
ServiceHostingType
|
Whether a service is offered once per system or once per manager. |
ServiceOptions
|
Options for a service that this manager offers. |
ServiceStatus
|
What the manager knows about the addressed service. |
Status
|
The outcome of an RPC together with its message text. |
StatusCode
|
Outcome of an RPC. Values and names match msa::StatusCode (C++). |
StubOptions
|
Options for addressing a service that another manager offers. |
StubStatus
|
Where a stub stands between construction and being ready to call. |
API
class etm.wccoa.msa.base.AsyncUnaryCall(dispatcher: etm.wccoa.msa.base._dispatcher.OaDispatcher, context: Any, decode: collections.abc.Callable[, etm.wccoa.datatypes.OaVariant], send: collections.abc.Callable[[collections.abc.Callable], None])
Handle for a running unary RPC — waitable and awaitable at the same time.
This is deliberately not a concurrent.futures.Future:
cancel() aborts an RPC that is already running, not merely one that has not started yet.
Internally the handle does hold such a future, served by the callback executor,
so that no continuation ever runs on the OA thread.
Example
>>> call = stub.call_function_async("SayHello", "Bob")
>>> call.result(timeout=2.0) # blocking, from any thread
>>> await call # or, from any event loop
Initialization
Start the RPC by handing send the callback that ends it.
send runs on the OA thread and is expected to return at once; the response arrives later,
on that same thread.
result(timeout: float | None = None) → etm.wccoa.datatypes.OaVariant
Wait for the response and return it.
timeout is purely local: on expiry this raises TimeoutError while the RPC keeps running.
To limit the RPC itself, pass a deadline when starting the call.
- Returns: The response value.
-
Raises:
- RpcError – if the call failed.
-
TimeoutError – if
timeoutelapsed.
cancel() → None
Abort the RPC. The server learns about it and stops working on it.
property status : etm.wccoa.msa.base._status.Status | None
The final status, or None while the call is still running.
property response_headers : etm.wccoa.datatypes.Metadata | None
Headers sent ahead of the response, or None while the call is running.
They only become readable once the call has finished, because the layer below hands out all four values of a response at the same moment.
This can be found at: etm.wccoa.datatypes.Metadata
property trailing_headers : etm.wccoa.datatypes.Metadata | None
Trailers sent by the service, or None while the call is running.
This can be found at: etm.wccoa.datatypes.Metadata
add_done_callback(fn: collections.abc.Callable[[etm.wccoa.msa.base._client._call.AsyncUnaryCall], None]) → None
Register fn, called with this handle once the call finishes.
The callback runs on the callback executor — never on the OA thread and never on an event loop.
class etm.wccoa.msa.base.PayloadEncryptionMode
Bases: enum.IntEnum
How a service treats encrypted payloads.
Initialization
Initialize self. See help(type(self)) for accurate signature.
DEACTIVATED
0
Payload encryption is off.
OPTIONAL
1
Payload encryption is on but a client may do without it.
MANDATORY
2
Payload encryption is on and a client without it cannot connect.
as_integer_ratio()
bit_count()
bit_length()
conjugate()
class denominator
class imag
class numerator
class real
to_bytes()
name()
value()
class etm.wccoa.msa.base.Responder
Bases: typing.Protocol
Answers a call that the handler chose not to answer by returning (S3).
send(response: etm.wccoa.datatypes.OaValueLike) → None
Send the response. May be called from any thread, exactly once.
send_error(error: Exception) → None
Fail the call. May be called from any thread, exactly once.
exception etm.wccoa.msa.base.RpcError(status: etm.wccoa.msa.base._status.Status, trailing_headers: etm.wccoa.datatypes.Metadata | None = None)
Bases: Exception
Raised when an RPC fails, and raised by a handler to fail it deliberately.
Raising this from a service handler transports both status and trailing_headers to the caller.
Any other exception is reported as StatusCode.UNKNOWN carrying str(exc); the traceback stays local.
Initialization
Initialize self. See help(type(self)) for accurate signature.
add_note()
class args
with_traceback()
class etm.wccoa.msa.base.ServerContext
Bases: typing.Protocol
What a handler can learn about the call it is serving.
The manager fills the Oa-Request-… headers itself,
so a handler can read the caller’s identity from request_headers
and answer with StatusCode.PERMISSION_DENIED if it does not like it.
property method : str
The wire name of the called method.
property deadline : datetime.datetime | None
When the caller stops waiting, or None if unlimited.
property request_headers : etm.wccoa.datatypes.Metadata
Headers sent by the caller, including the Oa-Request-… set.
This can be found at: etm.wccoa.datatypes.Metadata
property response_headers : etm.wccoa.datatypes.Metadata
Headers to send ahead of the response; a handler may add to these.
This can be found at: etm.wccoa.datatypes.Metadata
property trailing_headers : etm.wccoa.datatypes.Metadata
Trailers to send after the response; a handler may add to these.
This can be found at: etm.wccoa.datatypes.Metadata
property cancellation : threading.Event
Set once the caller canceled or the deadline expired.
A handler may check it with is_set() or sleep on it with wait() instead of blocking outright.
class etm.wccoa.msa.base.ServiceBase(service_name: str, protocol_type: str, protocol_version: int)
Common state of a service: its name and its method table.
The method table maps wire names to handlers that work on serialized payloads; adding a payload type is the job of the protocol layer.
Initialization
Build the native service; the protocol layer supplies its identity.
property service_name : str
The name this service is registered under.
class etm.wccoa.msa.base.ServiceContainer(manager: etm.wccoa.manager.Manager)
Registers services, starts them, and shuts their threads down again.
MSA itself has no stop; a container ends by being closed or by the process ending. Because every service owns a thread, Python is the first binding that has to join something, which is what the context manager is for.
Example
>>> with ServiceContainer(mgr) as container:
... container.register_service(GreeterService())
... container.start_all_services()
Initialization
register_service(service: etm.wccoa.msa.base._server._service.ServiceBase, options: etm.wccoa.msa.base._options.ServiceOptions | None = None) → None
Add a service.
This must happen before start_all_services().
The options are read here, so the same object may be configured further and used again for the next registration.
-
Raises:
- RuntimeError – if the services have already been started.
- ValueError – if the service name is invalid, or if a service of the same name and options is already registered.
start_all_services() → None
Announce all registered services and start their threads.
-
Raises:
-
RpcError
– with
StatusCode.UNAVAILABLEif the manager is already stopping, or if the server could not be announced.
-
RpcError
– with
close() → None
Stop the service threads and release the native server.
Requests that are still waiting are answered as canceled. Idempotent.
class etm.wccoa.msa.base.ServiceHostingReplica
Bases: enum.IntEnum
Which half of a redundant system hosts the service.
Initialization
Initialize self. See help(type(self)) for accurate signature.
NONE
0
Not a redundant system, or the replica does not matter.
LEFT
1
The first replica.
RIGHT
2
The second replica.
as_integer_ratio()
bit_count()
bit_length()
conjugate()
class denominator
class imag
class numerator
class real
to_bytes()
name()
value()
class etm.wccoa.msa.base.ServiceHostingType
Bases: enum.IntEnum
Whether a service is offered once per system or once per manager.
Initialization
Initialize self. See help(type(self)) for accurate signature.
GLOBAL
0
One service for the whole system; the client does not address a manager.
MANAGER_SPECIFIC
1
One service per manager; the client addresses type, number and replica.
as_integer_ratio()
bit_count()
bit_length()
conjugate()
class denominator
class imag
class numerator
class real
to_bytes()
name()
value()
class etm.wccoa.msa.base.ServiceOptions
Options for a service that this manager offers.
Example
>>> ServiceOptions().with_manager_specific_service()
ServiceOptions(hosting=<ServiceHostingType.MANAGER_SPECIFIC: 1>, ...)
hosting : etm.wccoa.msa.base._options.ServiceHostingType
None
Whether the service is global or manager specific.
service_name_suffix : str = <Multiline-String>
payload_encryption : etm.wccoa.msa.base._options.PayloadEncryptionMode | None
None
None falls back to the project setting, mirroring std::optional.
with_global_service() → etm.wccoa.msa.base._options.ServiceOptions
Switch to global hosting and return self.
- Returns: These options, for chaining.
with_manager_specific_service() → etm.wccoa.msa.base._options.ServiceOptions
Switch to manager specific hosting and return self.
- Returns: These options, for chaining.
class etm.wccoa.msa.base.ServiceStatus
Bases: enum.IntEnum
What the manager knows about the addressed service.
Initialization
Initialize self. See help(type(self)) for accurate signature.
UNKNOWN
None
The status could not be determined.
ERROR
0
The service is in an error state, or the service itself is unknown.
UNAVAILABLE
1
The service exists but is not reachable, for instance because its manager is down.
READY
2
The service accepts messages.
as_integer_ratio()
bit_count()
bit_length()
conjugate()
class denominator
class imag
class numerator
class real
to_bytes()
name()
value()
class etm.wccoa.msa.base.Status
The outcome of an RPC together with its message text.
OK : ClassVar[etm.wccoa.msa.base._status.Status]
None
Successful call without a text, matching msa::Status::OK.
CANCELED : ClassVar[etm.wccoa.msa.base._status.Status]
None
Canceled call without a text, matching msa::Status::CANCELED.
UNKNOWN : ClassVar[etm.wccoa.msa.base._status.Status]
None
Unknown failure without a text, matching msa::Status::UNKNOWN.
code : etm.wccoa.msa.base._status.StatusCode
None
text : str = <Multiline-String>
property is_ok : bool
True if code is StatusCode.OK.
class etm.wccoa.msa.base.StatusCode
Bases: enum.IntEnum
Outcome of an RPC. Values and names match msa::StatusCode (C++).
Initialization
Initialize self. See help(type(self)) for accurate signature.
OK
0
The call succeeded.
CANCELED
1
The call was canceled, typically by the caller.
UNKNOWN
2
Unknown error — also the fallback for an unhandled handler exception.
INVALID_ARGUMENT
3
The client specified an invalid argument.
DEADLINE_EXCEEDED
4
The deadline expired before the call could complete.
NOT_FOUND
5
A requested entity was not found.
ALREADY_EXISTS
6
The entity a client attempted to create already exists.
PERMISSION_DENIED
7
The caller is not authorized to execute the operation.
RESOURCE_EXHAUSTED
8
A resource has been exhausted.
FAILED_PRECONDITION
9
The system is not in a state required for the operation.
ABORTED
10
The operation was aborted.
OUT_OF_RANGE
11
The operation was attempted past the valid range.
UNIMPLEMENTED
12
The method is not implemented or not registered by the service.
INTERNAL
13
Framework failure — serialization, deserialization or dispatch.
UNAVAILABLE
14
The service is currently unavailable, for example while shutting down.
DATA_LOSS
15
Unrecoverable data loss or corruption.
UNAUTHENTICATED
16
The caller could not be authenticated.
as_integer_ratio()
bit_count()
bit_length()
conjugate()
class denominator
class imag
class numerator
class real
to_bytes()
name()
value()
class etm.wccoa.msa.base.StubOptions
Options for addressing a service that another manager offers.
The manager fields are only read when hosting is ServiceHostingType.MANAGER_SPECIFIC;
use with_manager_specific_service() to set them together.
hosting : etm.wccoa.msa.base._options.ServiceHostingType
None
Whether the addressed service is global or manager specific.
manager_type : etm.wccoa.datatypes.OaManagerType
manager_number : int
0
Number of the hosting manager.
replica : etm.wccoa.msa.base._options.ServiceHostingReplica
None
Replica of the hosting manager in a redundant system.
dist_system_name : str = <Multiline-String>
service_name_suffix : str = <Multiline-String>
with_global_service() → etm.wccoa.msa.base._options.StubOptions
Switch to global hosting and return self.
- Returns: These options, for chaining.
with_manager_specific_service(manager_type: etm.wccoa.datatypes.OaManagerType, manager_number: int, replica: etm.wccoa.msa.base._options.ServiceHostingReplica = ServiceHostingReplica.NONE) → etm.wccoa.msa.base._options.StubOptions
Switch to manager specific hosting, set the address, return self.
- Returns: These options, for chaining.
class etm.wccoa.msa.base.StubStatus
Bases: enum.IntEnum
Where a stub stands between construction and being ready to call.
Initialization
Initialize self. See help(type(self)) for accurate signature.
CREATED
0
Constructed; the constructor does not communicate.
ON_INIT
1
Initialization is running.
INIT_FAILED
2
Initialization failed; calls will fail too.
INIT_DONE
3
Ready to call.
