Accumulator values are reset when having multiple server instances

Jörga year ago

Hi

We have one dedicated server instance for receiving device data and one instance for serving the frontend. We are using the redis based broadcastservice. When an accumulator value (totalDistance) is set via instance 2 via DeviceResource.updateAccumulators() that value is written into the DB but overwritten by instance 1 with the next incoming datapoints.

I am looking at the code

https://github.com/traccar/traccar/blob/master/src/main/java/org/traccar/api/resource/DeviceResource.java#L153

I am seeing that this has been sent

device 1a73219e-8c85-4816-9d13-83442b68145f:{"device":null,"position":{"id":171709871,"attributes":{"priority":0,"sat":38,"event":0,"in1":false,"engineA":false,"engineB":false,"out1":false,"io71":3,"motion":false,"rssi":4,"io200":0,"ignition":false,"io9":24056,"io10":23,"io11":4775,"io245":3,"power":23.924,"io24":0,"io70":328,"io72":192,"io73":3000,"accelX":46,"accelY":959,"accelZ":20,"operator":xxx,"io216":0,"io62":2954207233641481458,"io63":0,"distance":0.0,"totalDistance":11000.0,"standbyDistance":0.0,"totalStandbyDistance":36.91,"xxx":false,"xxx":"19.200000000000003 °C","color":"neutral","hours":360186489,"idleTime":186489,"hoursB":0},"deviceId":439,"protocol":"xxx","serverTime":"2024-02-09T12:54:34.000+00:00","deviceTime":"2024-02-09T12:54:28.000+00:00","fixTime":"2024-02-09T12:54:28.000+00:00","outdated":false,"valid":true,"latitude":xxx,"longitude":xxx,"altitude":52.0,"speed":0.0,"course":0.0,"address":null,"accuracy":0.0,"network":null,"geofenceIds":null},"userId":null,"event":null,"commandDeviceId":null,"invalidateObject":null,"invalidatePermission":null}

I am seeing an incoming message in BaseBroadcastService.handleMessage()

But in the DB I am seeing one single position with the new value and the next position with the old one. So apparently instance 2 uses the cached position which had not been updated

Any ideas?

Jörga year ago

Correction: So apparently instance 1 uses the cached position which had not been updated

Jörga year ago

I am seeing that ConnectionManager.updatePosition() is called in instance 1 from BaseBroadcastService.handleMessage().
I don't see a call to CacheManager.updatePosition() though

Jörga year ago

I am seeing a call to updatePosition(local=false, ...)

https://github.com/traccar/traccar/blob/master/src/main/java/org/traccar/broadcast/BaseBroadcastService.java#L103

but an implementation of CacheManager.updatePosition() without the local param

https://github.com/traccar/traccar/blob/master/src/main/java/org/traccar/session/cache/CacheManager.java#L183

So that method will never be called from BaseBroadcastService.handleMessage(). Is that intended?

Jörga year ago

I am seeing three registered listeners to the broadcast service and it seems that the CacheManager is one of them

Anton Tananaeva year ago

It could be a race condition if you receive a new location and update at the same time.

Jörga year ago

There is a potential for a race condition here, but this is not it. The position in the cache manager is never updated in such a case - due to the design of the code. And I assume that this is not the intention.

Anton Tananaeva year ago

Yeah, I think that's because we assume that the position data is coming only from a device.