Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
ports:
- 27017:27017
env:
METEOR_RELEASE: '3.4'
METEOR_RELEASE: '3.5.3'

steps:
- uses: actions/checkout@v7
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/test-ingest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ jobs:
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc

# mongo-unit needs libssl1.1
- name: Install libssl1.1
run: |
Expand Down
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
4 changes: 2 additions & 2 deletions README-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

## Requirements

* `node` v22 and `nvm`
* Meteor 3.4
* `node` v24 and `nvm`
* Meteor 3.5.3
```
npx meteor
```
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Robot Agent (on-device)
## Tech Stack

- **Meteor 3** with React 18 and Material UI
- **Node.js v22**
- **Node.js v24**
- **MongoDB** for persistence
- **Mosquitto MQTT** broker with go-auth plugin
- **Protocol Buffers** for message serialization
Expand Down
4 changes: 4 additions & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ _build

# Unit test results. Normally ran on Github actions, but ignored anyway
unit_server.xml

# Meteor Modern-Tools build context directories
*/build-assets*
*/build-chunks*
18 changes: 9 additions & 9 deletions app/.meteor/packages
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@

meteor-base@1.5.2 # Packages every Meteor app needs to have
mobile-experience@1.1.2 # Packages for a great mobile UX
mongo@2.2.0 # The database Meteor supports right now
mongo@2.5.1 # The database Meteor supports right now
reactive-var@1.0.13 # Reactive variable for tracker

standard-minifier-css@1.10.0 # CSS minifier run for production mode
standard-minifier-css@1.10.1 # CSS minifier run for production mode
standard-minifier-js@3.2.0 # JS minifier run for production mode
es5-shim@4.8.1 # ECMAScript 5 compatibility for older browsers
ecmascript@0.17.0 # Enable ECMAScript2015+ syntax in app code
typescript@5.9.3 # Enable TypeScript syntax in .ts and .tsx modules
shell-server@0.7.0 # Server-side component of the `meteor shell` command
hot-module-replacement@0.5.4 # Update client in development without reloading the page
ecmascript@0.19.1 # Enable ECMAScript2015+ syntax in app code
typescript@5.11.1 # Enable TypeScript syntax in .ts and .tsx modules
shell-server@0.7.1 # Server-side component of the `meteor shell` command
hot-module-replacement@0.6.0 # Update client in development without reloading the page

static-html@1.5.0 # Define static page content in .html files
webapp@2.1.0
webapp@2.3.0
react-meteor-data # React higher-order component for reactively tracking Meteor data
accounts-base@3.2.0
accounts-base@3.3.1
accounts-google
accounts-github
accounts-oauth
service-configuration

rspack@1.0.0 # Integrate Rspack into Meteor for client and server app bundling
rspack@1.3.0 # Integrate Rspack into Meteor for client and server app bundling
aldeed:collection2
aldeed:simple-schema
percolate:migrations
Expand Down
2 changes: 1 addition & 1 deletion app/.meteor/release
Original file line number Diff line number Diff line change
@@ -1 +1 @@
METEOR@3.4
METEOR@3.5.3
74 changes: 37 additions & 37 deletions app/.meteor/versions
Original file line number Diff line number Diff line change
@@ -1,96 +1,96 @@
accounts-base@3.2.0
accounts-base@3.3.1
accounts-github@1.5.1
accounts-google@1.4.1
accounts-oauth@1.4.6
accounts-passwordless@3.1.0
accounts-oauth@1.4.7
accounts-passwordless@3.1.1
aldeed:collection2@4.1.5
aldeed:simple-schema@1.13.1
allow-deny@2.1.0
allow-deny@2.1.1
autoupdate@2.0.1
babel-compiler@7.13.0
babel-compiler@7.15.1
babel-runtime@1.5.2
base64@1.0.13
binary-heap@1.0.12
base64@1.0.14
binary-heap@1.0.13
boilerplate-generator@2.1.0
caching-compiler@2.0.1
callback-hook@1.6.1
callback-hook@1.8.0
check@1.5.0
core-runtime@1.0.0
ddp@1.4.2
ddp-client@3.1.1
ddp-common@1.4.4
ddp-rate-limiter@1.2.2
ddp-server@3.1.2
ddp-client@3.4.1
ddp-common@1.4.5
ddp-rate-limiter@1.3.0
ddp-server@3.4.1
diff-sequence@1.1.3
dynamic-import@0.7.4
ecmascript@0.17.0
dynamic-import@0.8.0
ecmascript@0.19.1
ecmascript-runtime@0.8.3
ecmascript-runtime-client@0.12.3
ecmascript-runtime-client@0.13.0
ecmascript-runtime-server@0.11.1
ejson@1.1.5
email@3.1.2
ejson@1.2.0
email@3.2.0
es5-shim@4.8.1
facts-base@1.0.2
fetch@0.1.6
fetch@0.2.0
geojson-utils@1.0.12
github-oauth@1.4.2
google-oauth@1.4.5
google-oauth@1.5.0
hot-code-push@1.0.5
hot-module-replacement@0.5.4
hot-module-replacement@0.6.0
http@1.4.4
id-map@1.2.0
inter-process-messaging@0.1.2
inter-process-messaging@0.1.3
launch-screen@2.0.1
lmieulet:meteor-coverage@5.0.0
localstorage@1.2.1
logging@1.3.6
meteor@2.2.0
meteor@2.3.1
meteor-base@1.5.2
meteortesting:browser-tests@1.8.0
meteortesting:mocha@3.3.0
meteortesting:mocha-core@8.2.0
minifier-css@2.0.1
minifier-js@3.1.0
minimongo@2.0.5
minifier-css@2.0.2
minifier-js@3.3.1
minimongo@2.2.0
mobile-experience@1.1.2
mobile-status-bar@1.1.1
modern-browsers@0.2.3
modules@0.20.3
modules-runtime@0.13.2
modules-runtime-hot@0.14.3
mongo@2.2.0
mongo@2.5.1
mongo-decimal@0.2.0
mongo-dev-server@1.1.1
mongo-id@1.0.9
npm-mongo@6.16.1
oauth@3.0.2
npm-mongo@6.16.3
oauth@3.0.4
oauth2@1.3.3
ordered-dict@1.2.0
percolate:migrations@2.0.1
promise@1.0.0
raix:eventemitter@1.0.0
random@1.2.2
rate-limit@1.1.2
rate-limit@1.2.0
react-fast-refresh@0.3.0
react-meteor-data@4.0.1
reactive-var@1.0.13
reload@1.3.2
retry@1.1.1
reywood:publish-composite@1.9.0
routepolicy@1.1.2
rspack@1.0.0
rspack@1.3.0
service-configuration@1.3.5
sha@1.0.10
shell-server@0.7.0
socket-stream-client@0.6.1
standard-minifier-css@1.10.0
shell-server@0.7.1
socket-stream-client@0.7.1
standard-minifier-css@1.10.1
standard-minifier-js@3.2.0
static-html@1.5.0
static-html-tools@1.0.0
tools-core@1.0.0
tools-core@1.3.0
tracker@1.3.4
typescript@5.9.3
url@1.3.5
webapp@2.1.0
typescript@5.11.1
url@1.3.6
webapp@2.3.0
webapp-hashing@1.1.2
zodern:types@1.0.13
10 changes: 5 additions & 5 deletions app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# syntax=docker/dockerfile:1.7
#
# Multi-stage build for the oro-app Meteor 3.4 web service.
# Multi-stage build for the oro-app Meteor 3.5 web service.
#
# Stage 1 (builder) installs Meteor and produces a self-contained Node bundle.
# Stage 2 (runtime) carries only the bundle plus a Node 22 runtime, ca-certs,
# Stage 2 (runtime) carries only the bundle plus a Node 24 runtime, ca-certs,
# tini, and curl (used by HEALTHCHECK).
#
# Build context: app/
Expand All @@ -13,10 +13,10 @@
# -----------------------------------------------------------------------------
# Stage 1: builder
# -----------------------------------------------------------------------------
FROM node:22-bookworm AS builder
FROM node:24-bookworm AS builder

# Pin the Meteor release to match app/.meteor/release.
ARG METEOR_RELEASE=3.4
ARG METEOR_RELEASE=3.5.3
# Architecture for `meteor build`. Override to os.linux.aarch64 for arm64.
ARG METEOR_ARCH=os.linux.x86_64

Expand Down Expand Up @@ -61,7 +61,7 @@ RUN cd /home/node/build/bundle/programs/server \
# -----------------------------------------------------------------------------
# Stage 2: runtime
# -----------------------------------------------------------------------------
FROM node:22-bookworm-slim AS runtime
FROM node:24-bookworm-slim AS runtime

# tini → PID 1, forwards signals to Node so docker stop is fast.
# curl → used by HEALTHCHECK below; kept as a runtime dep on purpose.
Expand Down
57 changes: 37 additions & 20 deletions app/imports/server/status.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { isString } from 'lodash';
// ORO modules
import { COLLECTIONS } from '../shared/constants';
import { ACCESS_LEVEL_VIEW } from '../shared/roles';
import { DiffSequence } from 'meteor/diff-sequence';
import { matchesStatusFilter } from '../shared/status';
import { Robots } from '../lib/collections';
import OroRoles from '../server/roles';
Expand Down Expand Up @@ -81,35 +82,51 @@ export default class RobotStatusManager {
);
const collectionName = COLLECTIONS.ROBOTS_WITH_STATUS;

const matchesFilter = (doc) => {
const aggStatusValue = calculateAggregatedStatusValue(doc.statuses);
return [matchesStatusFilter(statusFilter, aggStatusValue), aggStatusValue];
};
const toFields = ({ _id, ...fields }, aggStatusValue) => (
{ ...fields, [AGG_STATUS_FIELD]: aggStatusValue }
);

const robotCollHandle = await RobotsWithStatus.find(
{},
// This cursor is over a MongoDB *view*: writes happen to the underlying
// robots/robot_status collections, so the view itself never produces
// oplog entries and the oplog observe driver never sees a change (initial
// results work, live updates never arrive). Force the poll-and-diff
// driver; pollingIntervalMs only applies to it anyway.
// oplog entries, and MongoDB rejects `watch()` on a view
// (CommandNotSupportedOnView), so neither the oplog nor the change-stream
// observe driver ever sees a change (initial results work, live updates
// never arrive). Force the poll-and-diff driver: `disableOplog` opts out
// of oplog tailing, and the *ordered* observe below (addedAt/changedAt)
// opts out of change streams, which only serve unordered observes
// (Meteor 3.5 ignores `disableOplog` when picking change streams).
// pollingIntervalMs only applies to the polling driver anyway.
{ disableOplog: true, pollingIntervalMs: 3000 }
).observeChangesAsync({
added: (id, doc) => {
const aggStatusValue = calculateAggregatedStatusValue(doc.statuses);
if (matchesStatusFilter(statusFilter, aggStatusValue)) {
this.added(collectionName, id, { ...doc, [AGG_STATUS_FIELD]: aggStatusValue });
).observeAsync({
addedAt: (doc) => {
const [matches, aggStatusValue] = matchesFilter(doc);
if (matches) {
this.added(collectionName, doc._id, toFields(doc, aggStatusValue));
}
},
changed: (id, fields) => {
if (fields.statuses !== undefined) {
const aggStatusValue = calculateAggregatedStatusValue(fields.statuses);
if (matchesStatusFilter(statusFilter, aggStatusValue)) {
this.changed(collectionName, id, { ...fields, [AGG_STATUS_FIELD]: aggStatusValue });
} else {
this.removed(collectionName, id);
}
} else {
this.changed(collectionName, id, fields);
changedAt: (newDoc, oldDoc) => {
const [matches, aggStatusValue] = matchesFilter(newDoc);
const [matchedBefore] = matchesFilter(oldDoc);
if (matches && matchedBefore) {
this.changed(collectionName, newDoc._id, {
...DiffSequence.makeChangedFields(newDoc, oldDoc), [AGG_STATUS_FIELD]: aggStatusValue
});
} else if (matches) {
this.added(collectionName, newDoc._id, toFields(newDoc, aggStatusValue));
} else if (matchedBefore) {
this.removed(collectionName, newDoc._id);
}
},
removed: (id) => {
this.removed(collectionName, id);
removedAt: (oldDoc) => {
if (matchesFilter(oldDoc)[0]) {
this.removed(collectionName, oldDoc._id);
}
}
});

Expand Down
Loading
Loading