Skip to content

Instantly share code, notes, and snippets.

@dimaqq
Last active March 5, 2025 05:57
Show Gist options
  • Save dimaqq/b365fb399556feeced28a7d0d2e106d5 to your computer and use it in GitHub Desktop.
Save dimaqq/b365fb399556feeced28a7d0d2e106d5 to your computer and use it in GitHub Desktop.
class TracingEvents(Protocol):
@property
def request(self) -> EventSource: ...
def broken(self) -> EventSource: ...
class CertEvents(Protocol):
@property
def something(self) -> EventSource: ...
def other(self) -> EventSource: ...
class TracingRequirerProtocol(Protocol):
@property
def on(self) -> TracingEvents: ...
def is_ready(self) -> bool: ...
def get_endpoint(self, protocol: str) -> str|None:
...
class CertificatesRequirerProtocol(Protocol):
@property
def on(self) -> CertEvents: ...
def is_ready(self) -> bool: ...
def write(self, file_obj: xxx) -> None:
...
class Tracing(ops.Object):
def __init__(
self,
charm: ops.CharmBase,
tracing_requirer: TracingRequirerProtocol,
certificates_requirer: CertificatesRequirerProtocol | None = None)
):
self.tracing_requirer = tracing_requirer
self.certificates_requirer = certificates_requirer
for evt in (... the events for the above two ...):
self.framework.observe(evt, self.reconcile)
def reconcile(self):
rv = None, None
if not self.tracing_requirer.is_ready():
return
endpoint = self.tracing_requirer.get_endpoint("otlp_http")
if not endpoint:
return
if not self.certificates_requirer.is_reaady():
return
...
# Finally
self.charm.xxx.set_tracing_destination(*rv)
@dimaqq
Copy link
Author

dimaqq commented Mar 5, 2025

Charmers are left with this much boiler-plate:

class Charm(ops.CharmBase):
    def __init__(self, framework):
        self.tracing_endpoint = TracingEndpointRequirer(
            charm,
            relation_name="tracing-relation-name-must-match-metadata",
            protocols=["otlp_http"],
        )
        self.certificates = CertificatesRequirer(
            charm,
            relation_name=...,
        )
        self.tracing = Tracing(self, self.tracing_endpoint, self.certificates)

@dimaqq
Copy link
Author

dimaqq commented Mar 5, 2025

Could be a little better as:

class Charm(ops.CharmBase):
    def __init__(self, framework):
        self.tracing = Tracing(
            self,
            TracingEndpointRequirer,
            "tracing-relation-name",
            CertificatesRequirer,
            "certificates-relation-name",
        )

we're responsible to instantiate the requirers and must replicate their __init__() in the protocols.
we don't need to vendor the requirer source code though.

@dimaqq
Copy link
Author

dimaqq commented Mar 5, 2025

Decision from the stand-up: let's vendor the charm libs.

  • easy to start
  • relatively easy to upgrade
  • the pydantic dep cost is manageable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment