Skip to main content

Applet-Synchronizer Changelog

Latest Beta Version​

[3.0.0] - 2026-09-21​

Added​

  • (public) join_group accepts an optional organizationUid. When the device sends it, it becomes the group prefix directly and neither Redis nor MongoDB is consulted — the lookup only runs for clients that don't. No deployed client sends it yet; docs/organization-scoping.md has what core and front-display need to implement.
  • (internal) Redis read-through cache (redis_dsn, required) in front of the deviceUid → organizationUid lookup that scopes sync groups, so it no longer queries MongoDB on every join_group. 6 h ±10 % TTL, negative caching for devices the database doesn't know, and concurrent joins of the same device share a single query — a reconnect storm no longer becomes a query storm. See docs/organization-scoping.md.
  • (internal) Prometheus metrics for organization resolution (sos_applet_synchronizer_organization_*): un-namespaced joins, resolution failures by reason, cache hits/misses/errors, database queries and the ones shared between concurrent joins. Resolution fails open silently, so organization_unprefixed_resolutions_total is the signal that group scoping is degraded — alert on it.
  • (public) GET /alive (liveness) and GET /ready (readiness) probes. /ready answers 503 until the socket handlers are attached — until then the port accepts connections no handler would answer. Neither checks MongoDB or Redis: /ready reports their state in its body only, because the service synchronizes without them. /status is unchanged.
  • (public) Configuration option allowSlaveBroadcast to allow slave devices to broadcast values to all devices in a group via update_sync_config event.
  • (public) Observability endpoints GET /dashboard (+ /dashboard/view) and GET /metrics (Prometheus, sos_applet_synchronizer_ prefix) surfacing sync counters, barrier fill latency, connected peers/active groups and duplicate-deviceIdentification group collisions.

Changed​

  • (public) GET /metrics moved to the monitoring port (MONITORING_PORT, default 9999) without a token.
  • (public) /alive and /ready also on the monitoring port, so the sos-service chart's default probes work.
  • (internal) Deployed via flux-sos (sos-service pipeline): per-MR previews, production and production-us1.
  • (internal) Config parsed by parseServiceConfig + zod; local overrides in config/env.{environment}.json.
  • (public) Hosted service runs on Node 24; @signageos/lib 23.x, @signageos/user-domain-model 44.x, mongoose 8.20.
  • (public) Abort barriers pending over 20s server-side and count them as dropped (env SYNC_BARRIER_TIMEOUT_MS, 0 disables).

Removed​

  • (internal) Legacy Helm chart under helm/; deployment (probes, redis_dsn) lives in flux-sos now.

Fixed​

  • (public) A group whose last peers disconnect simultaneously no longer throws an uncaught TypeError from the barrier's master lookup (see public/CHANGELOG.md), which left stale pending requests behind and skipped the device_status update to the surviving peers.
  • (public) join_group is now always acknowledged, so a server-side failure can no longer leave a device waiting indefinitely for an answer that never comes.
  • (internal) A join is no longer rejected when the organization cannot be resolved. Previously a device missing from the database failed with Device not found, and a slow or unavailable MongoDB blocked the join. Resolution now fails open to an un-prefixed group, so synchronization keeps working when the databases don't — at the cost of groups not being namespaced by organization until they recover.
  • (internal) Startup no longer blocks on MongoDB or Redis being reachable (5 s bound, then it serves anyway and the clients reconnect in the background), and shutdown no longer closes either connection twice.
  • (public) Evict empty sync groups from memory so the dashboard, metrics and the periodic status tick do not accumulate dead groups.
  • (public) Emit device_status on device disconnect for organization-prefixed groups.
  • (public) Register a joining peer only when deviceIdentification is provided (the guard was always true before).
  • (public) Handle leave_group on the server so client leaveGroup() acks instead of hanging.

Security​

  • (public) /dashboard(+/view) require dashboard_token (Bearer header or browser Basic prompt); 404 until set.

[2.2.0] - 2025-06-13​

Fixed​

  • (public) Picking master device in the group based on deviceIdentification alphabetical order instead of the device creation date (keep the logic same with client - front-display).

Added​

  • (public) Public build of the Applet Synchronizer service as @signageos/applet-synchronizer-public package in public registry npmjs.com.

[2.1.3] - 2024-11-13​

Fixed​

  • (public) Fixed race condition during startup where some nested process would throw an unhandled error before the global handler is registered.
  • (public) Status event contained group name with the internal organization uid prefix instead of the pure group name without the prefix.

[2.1.2] - 2024-01-18​

Security​

  • (public) CVE-2017-16137

[2.1.1] - 2023-12-20​

Fixed​

  • (public) Formatted repository

[2.1.0] - 2022-03-16​

Added​

  • (public) Sending information about connected devices in group

[2.0.1] - 2020-07-29​

Fixed​

  • (public) Failsafe connection to proprietary database replication

[2.0.0] - 2020-01-12​

Changed​

  • (public) Change database implementation from RethinkDB to MongoDB

[1.0.4] - 2019-07-16​

Fixed​

  • (public) Added missing /status page for healthcheck

[1.0.0] - 2018-07-17​

Added​

  • (public) Changelog file containing all changes in current project

Changed​

  • (public) Obfuscate all development details and publish a clean npm package that's safe to make public for on-premise installations