Working with Hub ConnectorFilter objects and Hub Label dictionaries#
Cegal Hub allows a user to work with multiple instances of a particular Connector type.
In certain scenarios a user may not care which instance of a Connector will service a Connector request and in fact it is preferable that a round-robin approach is used.
In other scenarios a user may wish to have more fined grained control over which instance of a given Connector type is targeted. In this case a user can pin a request to a particular Connector instance or a subset of instances satisfied by a label or set of labels advertised by the Connector.
In this notebook the Connector type we will work with is the Petrel Connector. We will spin up several instances of Petrel running in the background. Remember every instance of Petrel spun up uses a Petrel license.
Ensure the Cegal Hub Petrel plugin is installed.
Launch Cegal Hub in local mode from the terminal (Windows Terminal is recommended). Local mode runs both a Cegal Hub Server and Cegal Hub Agent together.
Import from Cegal Hub - we will bring in the ConnectorFilter object
[ ]:
from cegalprizm.hub import Hub, ConnectorFilter
Create a new Hub object
[ ]:
hub = Hub()
Although we will work with Petrel primarily we will demonstrate the difference between a strong handle and a weak handle to an instance of a Connector. We will do this with an Agent. An Agent is also a Connector type in Cegal Hub!
Get a strong handle to a specific instance of an Agent. We dont care which Agent (if there were multiple instances running, which there are not) but we want a strong handle to it.
[ ]:
strong_agent_ctx = hub.default_agent_ctx()
strong_agent_ctx
# You will see in the output that we have a ConnectorFilter object which has an id for a specific target connector.
# Whenever we use this strong_agent_context we will always target the same instance of the Agent.
Lets try something different and get a weak handle to an Agent or Agents by creating a non specific Agent context.
[ ]:
any_agent_ctx = hub.new_agent_ctx()
any_agent_ctx
# You will see in the output that we have no target connector id
# This means that any Agent the user has access to could receive any request we make using the context.
# In our scenario we only have 1 Agent connected to Cegal hub Server so its clear where the request will go.
Check the available Agents from the weak handle Agent context
[ ]:
any_agent_ctx.available
# we should see the expected Agent is available below
Another means to control which Connector or set of Connectors for a particular type you wish to target is to make use of the ConnectorFilter object when creating a new Agent context. First lets take a look at the labels the Agent supports by querying the Hub Server for all the Connectors that the user has running.
[ ]:
hub.print_query_connectors()
# The output below shows quite a lot of information but but notably it all pertains to a single Agent instance.
# at the bottom of the output you can see the key-value labels that the Agent supports. These particular keys are standard
# labels for all connector types. We will see later that certain Connector types can also define custom labels.
# Custom label values can change for a particular instance of a Connector and reflect the current state of the Connector instance.
Lets show an example of how we can target a Connector instance using labels in a ConnectorFilter.
[ ]:
labels = {"hostname":"<myhostname>"} # update <myhostname> with the hostname from the above output
cf = ConnectorFilter(labels_dict=labels)
ac = hub.new_agent_ctx(connector_filter=cf)
ac.available
# the output below should show there is 1 agent available which satisfies this label
Lets change the value of the label and see what happens
[ ]:
labels = {"hostname":"bad"} # we know the hostname doesn't exist
cf = ConnectorFilter(labels_dict=labels)
ac = hub.new_agent_ctx(connector_filter=cf)
ac.available
# the output below should show there are no available Agents!
We can also create a ConnectorFilter and pin to a particular instance of an agent based on its id
[ ]:
cf = ConnectorFilter(target_connector_id="<the id of the agent>") # use the value of the agent id in the output of the query
ac = hub.new_agent_ctx(connector_filter=cf)
ac.available
# the output below should again show the expected 1 agent available
Now lets spin up a couple of Petrel Connector instances in the background and have a look at the custom labels
[ ]:
my_agent_ctx= hub.default_agent_ctx()
petrel_1_ctx = my_agent_ctx.new_petrel_instance()
petrel_2_ctx = my_agent_ctx.new_petrel_instance()
# this will launch to new instances of petrel in the background. This will take some time!
# petrel_1_ctx and petrel_2_ctx are strong handles to those spawned instances of Petrel
Examine petrel_1_ctx
[ ]:
petrel_1_ctx
# we can see this is a strong handle to the Petrel instance with the connector id
Examine petrel_2_ctx
[ ]:
petrel_2_ctx
# we can see this is also a strong handle to the other Petrel instance with a different connector id
Load different projects into each instance of Petrel
[ ]:
petrel_1_ctx.load_project(path="C:\data\pet1.pet")
petrel_2_ctx.load_project(path="C:\data\GroningenHub2\GroningenHub2.pet")
Now query the Connectors joined into the Cegal Hub Server and look at the labels
[ ]:
hub.print_query_connectors()
# you can see that in addition to standard set of labels the Petrel Connector has a number of custom labels
Instead of relying on the existing strong handle Petrel contexts we can create a new Petrel context from a ConnectorFilter as with the Agent
[ ]:
petrel_labels = {"primary-project-path":"c:\data\pet1.pet"}
pcf = ConnectorFilter(labels_dict=petrel_labels)
pet_ctx = hub.new_petrel_ctx(connector_filter=pcf)
pet_ctx.available
We can update the ConnectorFilter with a bad path on the primary-project-path label and observe we now have no Petrel Connectors available
[ ]:
pet_ctx.connector_filter = ConnectorFilter(labels_dict={"primary-project-path":"some_bad_path"})
pet_ctx.available
# we can see there are no longer any Petrel Connectors available
We can use multiple labels that must be satisfied in a ConnectorFilter
[ ]:
pet_ctx.connector_filter = ConnectorFilter(labels_dict={"primary-project-path":"c:\data\pet1.pet", "petrel-major-version":"21"})
pet_ctx.available
# this uses an additional label that must also be satisfied
# in this case the major version number being 21 (corresponding to Petrel 2021)
[ ]: