Skip to content

Conversation

@dominiquekleeven
Copy link
Collaborator

@dominiquekleeven dominiquekleeven commented Jul 4, 2025


Changes

  • Extracted the OpenRemoteClient source from the base project to a separate package, managed via uv workspaces.
  • Refactored the OpenRemoteClient structure to use nested classes based on domain (e.g., assets, realms), resulting in a clearer and more intuitive API.
  • Added service.register for registering a service/microservice
  • Added service.deregister for deregistering a service/microservice
  • Added service.heartbeat for manually sending heartbeat pings
  • Added a scheduler (service_registrar.py) to the OpenRemoteClient for registering a service and periodically sending a heartbeat the registration alive

Other

  • Added additional test coverage for the OpenRemoteClient.

dominiquekleeven and others added 30 commits May 14, 2025 09:40
…directly to prevent inconsistent routing behaviour
Co-authored-by: Rich Turner <7072278+richturner@users.noreply.github.com>
…chunking for datapoint retrieval

Deprecated cutoff_timestamp
…via the service backend

Couple technical notes:
- Front-end initialises the manager.rest.api in the app layout after authentication has succeeded
- Auth service also adds the interceptor to Axios so that the manager.rest.api can use the token
- Removed proxy logic from service backend, so api routes, tests and service methods.
…an in the async event loop

It is because the underlying calls are synchronous by nature, in FastAPI endpoints marked with async are always ran in the eventloop even when blocking, when non async it attempts to coalasce and run requests in threads
…an in the async event loop

It is because the underlying calls are synchronous by nature, in FastAPI endpoints marked with async are always ran in the eventloop even when blocking, when non async it attempts to coalasce and run requests in threads
@wborn wborn requested a review from Copilot September 16, 2025 08:42
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 60 out of 66 changed files in this pull request and generated 6 comments.

Files not reviewed (1)
  • frontend/package-lock.json: Language not supported

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 63 to 64
x: The timestamp of the data point in milliseconds.
y: The value of the data point.
Copy link

Copilot AI Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring comment should be consistent with the field name. Since the field is named 'x', the comment should refer to 'x' rather than using 'The timestamp of the data point'.

Suggested change
x: The timestamp of the data point in milliseconds.
y: The value of the data point.
`x`: The timestamp of the data point in milliseconds.
`y`: The value of the data point.

Copilot uses AI. Check for mistakes.
Comment on lines 43 to 47
cutoff_timestamp: int | None = Field(
default=None,
description="Deprecated, use training_data_period instead.",
deprecated=True,
)
Copy link

Copilot AI Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deprecated cutoff_timestamp field should include information about when it will be removed to help users plan migration. Consider adding a deprecation timeline like 'Deprecated since v1.1, will be removed in v2.0'.

Copilot uses AI. Check for mistakes.
Comment on lines 145 to 151
const match = /P(?:T)?(\d+)([HMDWMOY]+)/.exec(duration);
return match ? parseInt(match[1], 10) : null;
}

// Extract the unit from the ISO 8601 Duration string
getUnitFromDuration(duration: string): TimeDurationUnit | null {
const match = /PT(\d+)([HM])/.exec(duration);
return match ? (match[2] as TimeDurationUnit) : null;
const match = /P(?:T)?(\d+)([HMDWMOY]+)/.exec(duration);
Copy link

Copilot AI Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern [HMDWMOY]+ allows multiple time units to be combined (e.g., 'HM', 'DWY'), which may not represent valid ISO 8601 durations. Consider using a more restrictive pattern like ([HMDWY]) to match only single valid time units.

Copilot uses AI. Check for mistakes.
# Construct JWKS URL using the provided keycloak_url
jwks_url = f"{issuer}{JWKS_ENDPOINT_PATH}"

try:
Copy link

Copilot AI Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using ENV.ML_VERIFY_SSL to control SSL verification could be a security risk if set to False in production. Consider adding a warning or restricting this to development environments only.

Suggested change
try:
try:
# Restrict disabling SSL verification to development environments only
if not ENV.ML_VERIFY_SSL:
# Check for environment indicator; default to 'production' if not present
environment = getattr(ENV, "ENVIRONMENT", "production").lower()
if environment not in ("development", "dev", "test", "testing"):
logger.error(
"SSL verification is disabled (ENV.ML_VERIFY_SSL=False) in a non-development environment (%s). This is a security risk.",
environment,
)
raise HTTPException(
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
detail="SSL verification cannot be disabled in production environments.",
)
else:
logger.warning(
"SSL verification is disabled (ENV.ML_VERIFY_SSL=False) in %s environment. This should only be used for local development or testing.",
environment,
)

Copilot uses AI. Check for mistakes.
# So we need to handle the conversion to seconds manually
if isinstance(parsed, Duration):
seconds = int(parsed.months * 30 * 24 * 60 * 60)
seconds += int(parsed.years * 365 * 24 * 60 * 60) # Not taking into account leap years is OK
Copy link

Copilot AI Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approximation of months as 30 days and years as 365 days could lead to inaccuracies over time. Consider documenting this limitation more prominently or using a more accurate calendar-aware calculation library.

Copilot uses AI. Check for mistakes.
Comment on lines +113 to +116
if not self.registered or not self.instance_id:
logger.warning("Cannot send heartbeat - service not registered, attempting re-registration")
self._register_service()
return
Copy link

Copilot AI Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The automatic re-registration on failed heartbeat could lead to infinite retry loops if registration consistently fails. Consider implementing exponential backoff or maximum retry limits to prevent resource exhaustion.

Copilot uses AI. Check for mistakes.
@dominiquekleeven
Copy link
Collaborator Author

Replaced with new PR with a clean commit history #42

@dominiquekleeven dominiquekleeven deleted the enhancement/openremote-client-service-register branch September 18, 2025 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Improvement of an existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants