-
-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Please describe.
The client object can schedule an operation on the server with noblock=True
and collect the reply later when its needed. For example:
msg_id = client.read_property("my_property", noblock=True)
# do many things
print("property value is :", client.read_reply(msg_id))
The above code snippet is possible for most operations on properties and actions with keyword argument noblock=True
.
We use a plain dictionary to store:
- the response cache in ZMQ protocol binding (
core.zmq.brokers.BaseZMQClient
) - the message map in
core.zmq.brokers.MessageMappedClientPool
- the noblock message IDs on the
ObjectProxy
(client.proxy.ObjectProxy
)
all of which play a role in the noblock
invokation. How it works:
- an operation is scheduled on the server and a message ID is returned to the client
- whenever a ZMQ client looks for a message from the server, if it does not receive a message for the current message ID its looking for, the response is still received but added to the cache.
- whenever a response is asked again from the client, say for a different operation, it is checked whether the response is available in the cache before listening on the socket.
- For
noblock
messages, if the response completed, the message would have usually arrived on the client and be added to the said cache. If not, it proceeds to look for it on the socket (with a timeout which is unfortunately currently disabled in v0.3 but was working in v0.2).
Replace all these caches with a TLRU cache so that the responses are automatically cleared after a certain period of time if the client never returns to ask for a noblock response. This is meant for conserving memory.
Use cases
This is a general pattern that I have used a lot in multi-client scenarios - an application that is connected to 100s for Things.
If you issued many noblock
messages and for some reason not look for the response, the application memory consumption increases.
Describe the solution you'd like
Rough steps:
- A TLRU cache based on a mapping is already implemented in
cachetools
, add it to pyproject.toml as a main dependency and import it in the specified files and replace the dictionary with this implementation. - Read the number of messages in the cache and the time to live from
global_config
object. Define two variablesCACHE_TTL
orCACHE_SIZE
(or similar sounding words) and set default values to 2 hours and 10000 messages. - Add tests (docs for later). Use a small value of the TTL to make sure it works.
- As an additional piece of refactoring work, make
MessageMappedClientPool.message_map
to reuse the_response_cache
variable ofBaseZMQClient
. Its a duplicate and mostly not necessary. The teststest_05
andtest_09
throughtest_12
must pass if this refactoring is correct. This piece of work is optional.
Additional context
For point 4 in "how it works" above, the timeout is not respected although accepted as an input parameter. Fix it if possible, its really important, if not, lets keep that later. There may be some information in the codebase for versions less than v0.3 on how it was working.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status