It's the cache as you suspect. A server restart is needed to reflect the change.
If you're using more recent version of Traccar, a restart is not required. You just need to wait for a device to reconnect. But a restart will force it immediately. In the future I recommend using API instead of modifying the database directly.
I am using the latest version of Traccar, but I let the device connect even if it is suspended or expired, to be able to send back a reply to that device (Teltonika) that will delete the data from device's internal memory. So device will have a valid session even if it is expired.
(If Teltonika device do not receive a response from the server, as a confirmation that the data it sent was received, will keep that data in memory, and will keep trying to resend ... but i want to delete the data from the device if device is expired, so i let the device conenct and get a session):
In ConnectionManager.java
:
...
if (device != null) {
unknownByEndpoint.remove(connectionKey);
//device.checkDisabled(); // commented out this line
...
because device.checkDisabled();
is throwing exceptions error in the log ... which I don't like, and are more expensive in terms of resources...
I do the checking inside device protocol, and just null the positions if device is disabled/expired.
I manage expiration time outside traccar (due to customer billing...) and I update device db records directly.
So what would the the best option to "reset" the device cache in case I have to update it's expiration time, while device IS connected to server ? (other than server restart).
Thx.
You haven't really explained why you can't use the API. That would be my recommendation.
Hello.
OK, I should use the API.
Would this be enough if I add a "reset" path to DeviceResource:
@Path("{id}/reset")
@POST
public Response resetDevice(@PathParam("id") long deviceId) throws StorageException {
// Check if the user has the appropriate permissions
...
Device device = storage.getObject(Device.class, new Request(
new Columns.All(),
new Condition.Equals("id", deviceId)));
if (device != null) {
// Clear the device session in ConnectionManager
connectionManager.removeDeviceSession(deviceId);
// Remove the device from CacheManager
cacheManager.removeDevice(deviceId, deviceId);
// Return a success response
return Response.noContent().build();
} else {
// If the device is not found, return 404
return Response.status(Response.Status.NOT_FOUND).build();
}
}
Is the order important ? like to remove first from cacheManager then connectionManager ?
Thx.
Not sure I understand what you're trying to do now.
well, instead to update the device expirationtime directly in db (which will require a server restart or a device reconnect - as you confirmed above) , I want to use the API as you recommended.
For this I should do just an Update of device and send new expirationtime: PUT /devices/{id} ?
But if my device is not actually disconnected from server, would this be enough? (is current device session cleared?)
(device is not disconnected because I accept connection even if it is expired/disabled, to send a response back, to make the device delete that data from memory).
Or, instead of Update device, (which may not clear existing device session) can I just initiate aconnectionManager.removeDeviceSession(deviceId);
andcacheManager.removeDevice(deviceId, deviceId);
by this simple addition to the API ?
Current connection session won't be cleared, but the device will have to reconnect eventually. So I guess it depends on your requirements. For most people if device works for a few more minutes is not a big deal. But if you really need to disconnect it immediately, then yes, you would have to change some code.
... the problem is not that the device remains connected some time AFTER expirationtime (if it just expired), but it does NOT RECONNECT if it was expired and expirationtime was updated (with a future date, like after client renewed subscription, and now he is expecting to see his device). The issue I have with my Teltonika devices is that these stay online all the time (is that normal ?) Only a server restart will force them offline (and clear the cache), so now I am doing a daily server restart - which I was hoping to avoid. So the question is: should be enough if I initiate aconnectionManager.removeDeviceSession(deviceId);
and cacheManager.removeDevice(deviceId, deviceId);
to reset the cached data for a device ?
Thx.
I can't answer something like this off the top of my head.
... take your time.. :-))
or the question can be: what else is required to clear a cached device ? (besides connectionManager.removeDeviceSession
, and cacheManager.removeDevice
)
Update:
I can not find a way to clear the cached data for a device, (like "simulate a server restart" without restarting)
These commands:
connectionManager.removeDeviceSession(deviceId);
cacheManager.removeDevice(deviceId, deviceId);
will output:
2024-10-03 17:33:53 INFO: Cache remove device 185 references 2 key ConnectionKey[localAddress=/[0:0:0:0:0:0:0:0]:5927, remoteAddress=/xxx.xxx.xxx.xxx:61460]
2024-10-03 17:33:53 INFO: Cache remove device 185 references 2 key 185
2024-10-03 17:33:53 INFO: Reset deviceID: 185
but device expirationtime remains the same (the old cached data).
So how to clear the cached device data without a server restart?
Thank you.
Hi.
I have updated the device expiration time in db (directly in db, not through the we interface),
but the new value is not detected in the device protocol.
I suspect a device cache thing.
Do i have to restart the server, or is there a way to clear device caching .
Thx