dsmq 0.3.0__py3-none-any.whl → 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
dsmq/dsmq.py CHANGED
@@ -10,6 +10,8 @@ DEFAULT_PORT = 30008
10
10
 
11
11
  N_RETRIES = 5
12
12
  FIRST_RETRY = 0.01 # seconds
13
+ TIME_TO_LIVE = 60 # seconds
14
+ TIME_TO_LIVE = 5 # seconds
13
15
 
14
16
 
15
17
  def start_server(host=DEFAULT_HOST, port=DEFAULT_PORT):
@@ -65,7 +67,10 @@ class DSMQClientSideConnection:
65
67
  raise RuntimeError("Connection terminated by server")
66
68
  msg_str = data.decode("utf-8")
67
69
  msg = json.loads(msg_str)
68
- return msg
70
+ try:
71
+ return msg["message"]
72
+ except KeyError:
73
+ return ""
69
74
 
70
75
  def put(self, topic, msg):
71
76
  msg = json.dumps({"action": "put", "topic": topic, "message": msg})
@@ -76,8 +81,9 @@ def _handle_client_connection(socket_conn):
76
81
  sqlite_conn = sqlite3.connect("file:mem1?mode=memory&cache=shared")
77
82
  cursor = sqlite_conn.cursor()
78
83
 
79
- creation_time = time.time()
80
- last_read = {}
84
+ client_creation_time = time.time()
85
+ last_read_times = {}
86
+ time_of_last_purge = time.time()
81
87
 
82
88
  while True:
83
89
  data = socket_conn.recv(1024)
@@ -120,10 +126,10 @@ VALUES (:timestamp, :topic, :message)
120
126
 
121
127
  elif msg["action"] == "get":
122
128
  try:
123
- last_read_time = last_read[topic]
129
+ last_read_time = last_read_times[topic]
124
130
  except KeyError:
125
- last_read[topic] = creation_time
126
- last_read_time = last_read[topic]
131
+ last_read_times[topic] = client_creation_time
132
+ last_read_time = last_read_times[topic]
127
133
  msg["last_read_time"] = last_read_time
128
134
 
129
135
  # This block allows for multiple retries if the database
@@ -156,7 +162,7 @@ AND timestamp = a.min_time
156
162
  result = cursor.fetchall()[0]
157
163
  message = result[0]
158
164
  timestamp = result[1]
159
- last_read[topic] = timestamp
165
+ last_read_times[topic] = timestamp
160
166
  except IndexError:
161
167
  # Handle the case where no results are returned
162
168
  message = ""
@@ -166,6 +172,20 @@ AND timestamp = a.min_time
166
172
  else:
167
173
  print("Action must either be 'put' or 'get'")
168
174
 
175
+ # Periodically clean out messages from the queue that are
176
+ # past their sell buy date.
177
+ # This operation is pretty fast. I clock it at 12 us on my machine.
178
+ if time.time() - time_of_last_purge > TIME_TO_LIVE:
179
+ cursor.execute(
180
+ """
181
+ DELETE FROM messages
182
+ WHERE timestamp < :time_threshold
183
+ """,
184
+ {"time_threshold": time_of_last_purge}
185
+ )
186
+ sqlite_conn.commit()
187
+ time_of_last_purge = time.time()
188
+
169
189
  sqlite_conn.close()
170
190
 
171
191
 
@@ -1,4 +1,3 @@
1
- import json
2
1
  import time
3
2
  import dsmq
4
3
 
@@ -1,5 +1,3 @@
1
- import json
2
- import socket
3
1
  import time
4
2
  import dsmq
5
3
 
@@ -1,8 +1,7 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dsmq
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: A dead simple message queue
5
- License-File: LICENSE
6
5
  Requires-Python: >=3.10
7
6
  Description-Content-Type: text/markdown
8
7
 
@@ -58,6 +57,24 @@ topic = "greetings"
58
57
  msg = mq.get(topic)
59
58
  ```
60
59
 
60
+ ### Spin up and shut down a dsmq in its own process
61
+
62
+ A dsmq server doesn't come with a built-in way to shut itself down.
63
+ It can be helpful to have it running in a separate process that can be
64
+ managed
65
+
66
+ ```python
67
+ import multiprocessing as mp
68
+
69
+ p_mq = mp.Process(target=dsmq.start_server, args=(config.MQ_HOST, config.MQ_PORT))
70
+ p_mq.start()
71
+
72
+ p_mq.join()
73
+ # or
74
+ p_mq.kill()
75
+ p_mq.close()
76
+ ```
77
+
61
78
  ### Demo
62
79
 
63
80
  1. Open 3 separate terminal windows.
@@ -0,0 +1,10 @@
1
+ dsmq/__init__.py,sha256=YCgbnQAk8YbtHRyMcU0v2O7RdRhPhlT-vS_q40a7Q6g,50
2
+ dsmq/demo_linux.py,sha256=7yLglGmirDLuuyMxppYSK-dfx2Fg2Q0dIWB4cl2yV1c,622
3
+ dsmq/dsmq.py,sha256=dKYtGkg8Kwll2sCytCqSI5klFs2cwm2pyXAkyQk4RdU,6206
4
+ dsmq/example_get_client.py,sha256=chFfB2949PBENmgdUc3ASrATq1m4wvHGBzEnOC-o_Xs,296
5
+ dsmq/example_put_client.py,sha256=mUKCRhmUieMZEpHLFWFvzeKB6IR7A8l4tWN8TvPzdKU,348
6
+ dsmq/example_server.py,sha256=kkXOPaaTzVxf9_iIM76zU9pZhkPna_1vcGWkPrhCjus,61
7
+ dsmq-0.5.0.dist-info/METADATA,sha256=EQISO0WcVsb7smXIie-ZP7pIO1itY8FZfjGw3DPuZDM,3878
8
+ dsmq-0.5.0.dist-info/WHEEL,sha256=3U_NnUcV_1B1kPkYaPzN-irRckL5VW_lytn0ytO_kRY,87
9
+ dsmq-0.5.0.dist-info/licenses/LICENSE,sha256=3Yu1mAp5VsKmnDtzkiOY7BdmrLeNwwZ3t6iWaLnlL0Y,1071
10
+ dsmq-0.5.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.25.0
2
+ Generator: hatchling 1.26.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
dsmq/py.typed DELETED
File without changes
@@ -1,11 +0,0 @@
1
- dsmq/__init__.py,sha256=YCgbnQAk8YbtHRyMcU0v2O7RdRhPhlT-vS_q40a7Q6g,50
2
- dsmq/demo_linux.py,sha256=7yLglGmirDLuuyMxppYSK-dfx2Fg2Q0dIWB4cl2yV1c,622
3
- dsmq/dsmq.py,sha256=7s-e2dmbaPMfmkrbY-CXZ5y9DmOQ9xBvoWATYGAKgGY,5483
4
- dsmq/example_get_client.py,sha256=VwL7Z7KdSDzbpdAhetcOY8KHVPjb6_OB5rtbI30CjJ0,308
5
- dsmq/example_put_client.py,sha256=CRVQhZTYXDawXSiJP997A0ttBwKuNf8QvSpvPmEP7ng,374
6
- dsmq/example_server.py,sha256=kkXOPaaTzVxf9_iIM76zU9pZhkPna_1vcGWkPrhCjus,61
7
- dsmq/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- dsmq-0.3.0.dist-info/METADATA,sha256=8Mxc1JRyO8BrRiT5eLeszE5zVYUDuwJvrqXq6HW6g2s,3513
9
- dsmq-0.3.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
10
- dsmq-0.3.0.dist-info/licenses/LICENSE,sha256=3Yu1mAp5VsKmnDtzkiOY7BdmrLeNwwZ3t6iWaLnlL0Y,1071
11
- dsmq-0.3.0.dist-info/RECORD,,