DI-Friendly OpcUaClient factory methods? #1549
Replies: 1 comment
-
The factory methods are calling the discovery services to select an endpoint and ultimately get an instance of
Yeah, the constructor does not connect. The trick will be creating the |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
(Currently; milo 1.0) all the factories for OpcUaClient (
OpcUaClient::create
) throwUaException
. Fail-fast behavior is a good design pattern and is desirable in a lot of circumstances.DI frameworks like guice and dagger don't really like it when a
Provider
throws checked or unchecked exceptions...There are definitely workarounds like guice's
ThrowingProvider
or putting@Nullable
everywhere you inject with dagger.A few ideas related to skirting this problem:
OpcUaClient
state via getters (i.e.public Service.State state()
) so milo API users can query state or add listeners for state transitions (NEW->STARTING, STARTING->RUNNING, RUNNING->STOPPING, ...)OpcUaClient
to be fully instantiated but not-yet-connected to an OpcUa server (I imagine this may be a headache as all public methods would have to check state before proceeding and throwIllegalStateException
if not started). This would need a factory method that creates anOpcUaClient
that hasn't attempted any server communication at all, delegating handling of anyUaException
(& friends) untilOpcUaClient::connect
orOpcUaClient::connectAsync
, or even some new method (i.e.OpcUaClient::start
) that performs all the bootstrap tasks except for callingOpcUaClient::connect
OpcUaClient
to be fully instantiated but locked in the connection attempt loop untilOpcTcpClientTransportConfig::getConnectTimeout
is hit. This is basically the same (possibly the same? correct me if I'm wrong here...) to the current behavior, except that the factory method that would create it would return a connecting client that has a time-bomb Exception waiting for you if you don't have a server plugged in. Ugly, but at least your injector can pass you a fully-instantiated OpcUaClient without hanging on the connection attempt or having to handle a checked exception.Related question: The constructor
public OpcUaClient(OpcUaClientConfig config, OpcClientTransport transport)
does not declare any checked exceptions, is it possible to create an instance ofOpcUaClient
without attempting a server connection of any sort with this constructor? I haven't really tinkered with this because I really do like the convenient stuff that happens behind the scenes when I use the factory methods.[Edit]:
NOTE: This is a common pattern for database, MQTT, and WebSocket client APIs I use and suggestions are based on those (though I can't say I've seen an HTTP client API that works like this, those I've use almost always fail fast like milo)
Beta Was this translation helpful? Give feedback.
All reactions