Skip to content
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

Service discovery #1423

Open
ggrossetie opened this issue Jan 8, 2023 · 3 comments
Open

Service discovery #1423

ggrossetie opened this issue Jan 8, 2023 · 3 comments
Labels
💡 proposal 🍩 enhancement New feature or request ☕ java Related to Java code

Comments

@ggrossetie
Copy link
Member

The goal is to allow the gateway server to register additional diagram libraries (that are not built-in).
One of the requirement will be to adhere to the Kroki companion container API specification (not yet available).

Proposal

Discovery

When the gateway server starts, it will probe the seed addresses by connecting to each address and attempting to identify the service. If successful, it will register a new service.

discovery.seed_resolver.timeout: 5s
discovery.seed_resolver.max_retry: 5
discovery.seed_hosts:
  - 192.168.1.10:1234
  - 192.168.1.11 
  - seeds.mydomain.com 

This solution implies that the service must provide information (at least a unique name, a version, and a list of supported formats).

Static registration

Alternatively, we could explicitly register services:

services:
  - name: sankey
    version: '1.2.3'
    endpoint: https://my.domain.org/sankey
    formats:
      - png
      - svg

In this case, the service does not have to expose an API that provides information.

Dynamic registration

We could also support dynamic registration. In this case, the companion service will be responsible for registering itself by sending a request to the gateway server.

POST https://my.kroki/services

{
  "name": "mscgen",
  "version": "1.2.3",
  "formats": ["png", "svg"]
}
  • 201 created: service registration is successful
  • 422 unprocessable entity: non-unique name (service is probably already registered)
  • 400 bad request: request payload is invalid
  • 500: unexpected error

Since Kroki is stateless, registry is held in memory. As a result, the companion service is responsible for registering again in case the gateway server is restarted.

For this reasons, services should send a heartbeat:

PUT https://my.kroki/services/mscgen/heartbeat
  • 200 ok: service found
  • 404 not found: service is not registered (use _links to indicate how to register)
  • 500: unexpected error

A service that receives a 404 during a heartbeat could then register again.

The gateway service will provide information about a registred service:

GET https://my.kroki/services/mscgen

{
  "name": "mscgen",
  "version": "1.2.3",
  "formats": ["png", "svg"],
  "created_at": "2023-01-01T15:50:05.815479Z",
  "updated_at": "2023-01-01T15:50:05.815479Z",
  "last_activity_at": "2023-01-01T18:55:04.187568Z"
}
  • 200 ok: service found
  • 404 not found: service is not registered
  • 500: unexpected error

Note: Last activity date is the last time a service sent a heartbeat or respond to a request from the gateway server.

I will also provide a list of all services currently registered:

GET https://my.kroki/services
[
  {
    "name": "mscgen",
    "version": "1.2.3",
    "_links": [
      {
        "rel": "self",
        "href": "/services/mscgen",
        "method": "GET"
      }
    ]
  }
]  

Unregister

A service can unregister (for instance when the service is shutting down) using:

DELETE https://my.kroki/services/mscgen
  • 200 ok: service removed
  • 404 not found: service is not registered
  • 500: unexpected error
@ggrossetie ggrossetie added 🍩 enhancement New feature or request ☕ java Related to Java code 💡 proposal labels Jan 8, 2023
@copyrights
Copy link
Contributor

I would add the possibility for an example key (may optional) .

GET https://my.kroki/services/blockdiag

{
  "name": "BlockDiag",
  "version": "1.2.3",
  "formats": ["png", "svg"],
  "example": "blockdiag {\n  Kroki -> generates -> \"Block diagrams\";\n  Kroki -> is -> \"very easy!\";\n\n  Kroki [color = \"greenyellow\"];\n  \"Block diagrams\" [color = \"pink\"];\n  \"very easy!\" [color = \"orange\"];\n}",
  "created_at": "2023-01-01T15:50:05.815479Z",
  "updated_at": "2023-01-01T15:50:05.815479Z",
  "last_activity_at": "2023-01-01T18:55:04.187568Z"
}

@ggrossetie
Copy link
Member Author

It's interesting to note that Vert.x has a service discovery library: https://vertx.io/docs/vertx-service-discovery/java/
One downside is that it would require companion service/container to use an EventBus client to register: https://github.com/vert-x3/vertx-eventbus-bridge-clients

Having said that, we could offer a REST API as a bridge and still leverage Vert.x service discovery library.

I would add the possibility for an example key (may optional) .

What would be the purpose?

@copyrights
Copy link
Contributor

to provide an example for a client application e.g. https://kroki.io. When you build something like that you may don't want to change your code for every new service provided via the api.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💡 proposal 🍩 enhancement New feature or request ☕ java Related to Java code
Projects
None yet
Development

No branches or pull requests

2 participants