dimples 1.1.0__tar.gz → 1.2.1__tar.gz

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.
Files changed (144) hide show
  1. {dimples-1.1.0 → dimples-1.2.1}/PKG-INFO +1 -1
  2. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/network/session.py +1 -0
  3. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/network/state.py +3 -2
  4. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/terminal.py +3 -4
  5. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/dbi/session.py +4 -2
  6. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/flexible.py +3 -2
  7. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/gatekeeper.py +4 -2
  8. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/queue.py +1 -1
  9. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/session.py +3 -1
  10. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/ws.py +3 -2
  11. {dimples-1.1.0 → dimples-1.2.1}/dimples/edge/octopus.py +11 -3
  12. {dimples-1.1.0 → dimples-1.2.1}/dimples/edge/start.py +1 -2
  13. {dimples-1.1.0 → dimples-1.2.1}/dimples/group/helper.py +2 -1
  14. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/dispatcher.py +12 -4
  15. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/packer.py +3 -1
  16. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/push.py +12 -4
  17. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/session.py +4 -11
  18. {dimples-1.1.0 → dimples-1.2.1}/dimples/station/handler.py +5 -2
  19. {dimples-1.1.0 → dimples-1.2.1}/dimples/utils/__init__.py +5 -40
  20. {dimples-1.1.0 → dimples-1.2.1}/dimples/utils/cache.py +28 -33
  21. dimples-1.2.1/dimples/utils/runner.py +24 -0
  22. {dimples-1.1.0 → dimples-1.2.1}/dimples.egg-info/PKG-INFO +1 -1
  23. {dimples-1.1.0 → dimples-1.2.1}/dimples.egg-info/SOURCES.txt +2 -1
  24. {dimples-1.1.0 → dimples-1.2.1}/dimples.egg-info/requires.txt +3 -3
  25. {dimples-1.1.0 → dimples-1.2.1}/setup.py +4 -4
  26. {dimples-1.1.0 → dimples-1.2.1}/README.md +0 -0
  27. {dimples-1.1.0 → dimples-1.2.1}/dimples/__init__.py +0 -0
  28. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/__init__.py +0 -0
  29. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/archivist.py +0 -0
  30. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/checkpoint.py +0 -0
  31. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/__init__.py +0 -0
  32. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/commands.py +0 -0
  33. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/creator.py +0 -0
  34. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/group.py +0 -0
  35. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/grp_expel.py +0 -0
  36. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/grp_invite.py +0 -0
  37. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/grp_join.py +0 -0
  38. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/grp_query.py +0 -0
  39. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/grp_quit.py +0 -0
  40. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/grp_reset.py +0 -0
  41. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/grp_resign.py +0 -0
  42. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/cpu/handshake.py +0 -0
  43. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/facebook.py +0 -0
  44. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/messenger.py +0 -0
  45. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/network/__init__.py +0 -0
  46. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/network/transition.py +0 -0
  47. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/packer.py +0 -0
  48. {dimples-1.1.0 → dimples-1.2.1}/dimples/client/processor.py +0 -0
  49. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/__init__.py +0 -0
  50. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/anonymous.py +0 -0
  51. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/ans.py +0 -0
  52. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/archivist.py +0 -0
  53. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/compat/__init__.py +0 -0
  54. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/compat/btc.py +0 -0
  55. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/compat/compatible.py +0 -0
  56. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/compat/entity.py +0 -0
  57. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/compat/meta.py +0 -0
  58. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/compat/network.py +0 -0
  59. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/dbi/__init__.py +0 -0
  60. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/dbi/account.py +0 -0
  61. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/dbi/message.py +0 -0
  62. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/facebook.py +0 -0
  63. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/messenger.py +0 -0
  64. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/packer.py +0 -0
  65. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/processer.py +0 -0
  66. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/protocol/__init__.py +0 -0
  67. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/protocol/ans.py +0 -0
  68. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/protocol/block.py +0 -0
  69. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/protocol/handshake.py +0 -0
  70. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/protocol/login.py +0 -0
  71. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/protocol/mute.py +0 -0
  72. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/protocol/report.py +0 -0
  73. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/register.py +0 -0
  74. {dimples-1.1.0 → dimples-1.2.1}/dimples/common/session.py +0 -0
  75. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/__init__.py +0 -0
  76. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/gate.py +0 -0
  77. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/mars.py +0 -0
  78. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/mtp.py +0 -0
  79. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/protocol/__init__.py +0 -0
  80. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/protocol/mars.py +0 -0
  81. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/protocol/ws.py +0 -0
  82. {dimples-1.1.0 → dimples-1.2.1}/dimples/conn/seeker.py +0 -0
  83. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/__init__.py +0 -0
  84. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/account.py +0 -0
  85. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/__init__.py +0 -0
  86. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/base.py +0 -0
  87. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/document.py +0 -0
  88. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/group.py +0 -0
  89. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/group_history.py +0 -0
  90. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/group_keys.py +0 -0
  91. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/login.py +0 -0
  92. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/meta.py +0 -0
  93. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/private.py +0 -0
  94. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/station.py +0 -0
  95. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/dos/user.py +0 -0
  96. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/message.py +0 -0
  97. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/session.py +0 -0
  98. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_cipherkey.py +0 -0
  99. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_document.py +0 -0
  100. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_group.py +0 -0
  101. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_group_history.py +0 -0
  102. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_group_keys.py +0 -0
  103. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_login.py +0 -0
  104. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_message.py +0 -0
  105. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_meta.py +0 -0
  106. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_private.py +0 -0
  107. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_station.py +0 -0
  108. {dimples-1.1.0 → dimples-1.2.1}/dimples/database/t_user.py +0 -0
  109. {dimples-1.1.0 → dimples-1.2.1}/dimples/edge/__init__.py +0 -0
  110. {dimples-1.1.0 → dimples-1.2.1}/dimples/edge/shared.py +0 -0
  111. {dimples-1.1.0 → dimples-1.2.1}/dimples/group/__init__.py +0 -0
  112. {dimples-1.1.0 → dimples-1.2.1}/dimples/group/admin.py +0 -0
  113. {dimples-1.1.0 → dimples-1.2.1}/dimples/group/builder.py +0 -0
  114. {dimples-1.1.0 → dimples-1.2.1}/dimples/group/delegate.py +0 -0
  115. {dimples-1.1.0 → dimples-1.2.1}/dimples/group/emitter.py +0 -0
  116. {dimples-1.1.0 → dimples-1.2.1}/dimples/group/manager.py +0 -0
  117. {dimples-1.1.0 → dimples-1.2.1}/dimples/group/packer.py +0 -0
  118. {dimples-1.1.0 → dimples-1.2.1}/dimples/register/__init__.py +0 -0
  119. {dimples-1.1.0 → dimples-1.2.1}/dimples/register/base.py +0 -0
  120. {dimples-1.1.0 → dimples-1.2.1}/dimples/register/ext.py +0 -0
  121. {dimples-1.1.0 → dimples-1.2.1}/dimples/register/run.py +0 -0
  122. {dimples-1.1.0 → dimples-1.2.1}/dimples/register/shared.py +0 -0
  123. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/__init__.py +0 -0
  124. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/archivist.py +0 -0
  125. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/cpu/__init__.py +0 -0
  126. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/cpu/ans.py +0 -0
  127. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/cpu/document.py +0 -0
  128. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/cpu/handshake.py +0 -0
  129. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/cpu/login.py +0 -0
  130. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/cpu/report.py +0 -0
  131. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/messenger.py +0 -0
  132. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/processor.py +0 -0
  133. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/session_center.py +0 -0
  134. {dimples-1.1.0 → dimples-1.2.1}/dimples/server/trace.py +0 -0
  135. {dimples-1.1.0 → dimples-1.2.1}/dimples/station/__init__.py +0 -0
  136. {dimples-1.1.0 → dimples-1.2.1}/dimples/station/shared.py +0 -0
  137. {dimples-1.1.0 → dimples-1.2.1}/dimples/station/start.py +0 -0
  138. {dimples-1.1.0 → dimples-1.2.1}/dimples/utils/config.py +0 -0
  139. {dimples-1.1.0 → dimples-1.2.1}/dimples/utils/dos.py +0 -0
  140. {dimples-1.1.0 → dimples-1.2.1}/dimples/utils/log.py +0 -0
  141. {dimples-1.1.0 → dimples-1.2.1}/dimples.egg-info/dependency_links.txt +0 -0
  142. {dimples-1.1.0 → dimples-1.2.1}/dimples.egg-info/entry_points.txt +0 -0
  143. {dimples-1.1.0 → dimples-1.2.1}/dimples.egg-info/top_level.txt +0 -0
  144. {dimples-1.1.0 → dimples-1.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dimples
3
- Version: 1.1.0
3
+ Version: 1.2.1
4
4
  Summary: DIMP Library for Edges and Stations
5
5
  Home-page: https://github.com/dimchat/demo-py
6
6
  Author: Albert Moky
@@ -118,6 +118,7 @@ class ClientSession(BaseSession):
118
118
  await fsm.start()
119
119
  # 3. start an async task for this session
120
120
  self.__daemon.start()
121
+ # await self.run()
121
122
 
122
123
  # Override
123
124
  async def stop(self):
@@ -31,7 +31,7 @@ from typing import Optional, Union
31
31
 
32
32
  from dimsdk import ID
33
33
 
34
- from startrek.fsm import Runner
34
+ from startrek.skywalker import Runner
35
35
  from startrek.fsm import Context, BaseTransition, BaseState, AutoMachine
36
36
  from startrek import Docker, DockerStatus
37
37
 
@@ -97,7 +97,8 @@ class StateMachine(AutoMachine, Context):
97
97
  else:
98
98
  session = self.session
99
99
  gate = session.gate
100
- task = Runner.async_run(coroutine=gate.fetch_docker([], remote=session.remote_address, local=None))
100
+ coro = gate.fetch_docker([], remote=session.remote_address, local=None)
101
+ task = Runner.async_task(coro=coro)
101
102
  task.add_done_callback(self._fetch_docker_callback)
102
103
  # waiting for callback
103
104
  return DockerStatus.ERROR
@@ -34,7 +34,8 @@ import time
34
34
 
35
35
  from dimples import EntityType
36
36
 
37
- from ..utils import DaemonRunner, Logging
37
+ from ..utils import Logging
38
+ from ..utils import Runner
38
39
  from ..utils import StateDelegate
39
40
 
40
41
  from .network import ClientSession
@@ -51,7 +52,7 @@ class DeviceMixin:
51
52
  return 'DIMP/0.4 (Client; Linux; en-US) DIMCoreKit/0.9 (Terminal) DIM-by-GSP/1.0'
52
53
 
53
54
 
54
- class Terminal(DaemonRunner, DeviceMixin, Logging, StateDelegate):
55
+ class Terminal(Runner, DeviceMixin, Logging, StateDelegate):
55
56
 
56
57
  def __init__(self, messenger: ClientMessenger):
57
58
  super().__init__(interval=60)
@@ -74,7 +75,6 @@ class Terminal(DaemonRunner, DeviceMixin, Logging, StateDelegate):
74
75
 
75
76
  # Override
76
77
  async def setup(self):
77
- await super().setup()
78
78
  session = self.session
79
79
  session.fsm.delegate = self
80
80
  await session.start()
@@ -82,7 +82,6 @@ class Terminal(DaemonRunner, DeviceMixin, Logging, StateDelegate):
82
82
  # Override
83
83
  async def finish(self):
84
84
  await self.session.stop()
85
- await super().finish()
86
85
 
87
86
  # Override
88
87
  async def process(self) -> bool:
@@ -213,11 +213,13 @@ class StationDBI(ABC):
213
213
  raise NotImplemented
214
214
 
215
215
  @abstractmethod
216
- async def add_station(self, identifier: Optional[ID], host: str, port: int, provider: ID, chosen: int = 0) -> bool:
216
+ async def add_station(self, identifier: Optional[ID], host: str, port: int, provider: ID,
217
+ chosen: int = 0) -> bool:
217
218
  raise NotImplemented
218
219
 
219
220
  @abstractmethod
220
- async def update_station(self, identifier: Optional[ID], host: str, port: int, provider: ID, chosen: int = None) -> bool:
221
+ async def update_station(self, identifier: Optional[ID], host: str, port: int, provider: ID,
222
+ chosen: int = None) -> bool:
221
223
  raise NotImplemented
222
224
 
223
225
  @abstractmethod
@@ -31,7 +31,7 @@
31
31
  from typing import Optional, Union, List
32
32
 
33
33
  from startrek.types import SocketAddress
34
- from startrek.fsm import Runner
34
+ from startrek.skywalker import Runner
35
35
  from startrek import Connection
36
36
  from startrek import Arrival, Departure
37
37
  from startrek import StarDocker
@@ -65,7 +65,8 @@ class FlexibleDocker(StarDocker, DeparturePacker):
65
65
  return None
66
66
  # OK
67
67
  docker.delegate = self.delegate
68
- Runner.async_run(coroutine=docker.set_connection(conn=self.connection))
68
+ coro = docker.set_connection(conn=self.connection)
69
+ Runner.async_task(coro=coro)
69
70
  self.__docker = docker
70
71
  return docker
71
72
 
@@ -182,7 +182,8 @@ class GateKeeper(Runner, DockerDelegate, Logging):
182
182
  # client
183
183
  assert address is not None, 'remote address empty'
184
184
  hub = StreamClientHub(delegate=delegate)
185
- Runner.async_run(coroutine=_client_connect(hub=hub, address=address))
185
+ coro = _client_connect(hub=hub, address=address)
186
+ Runner.async_task(coro=coro)
186
187
  self.info(msg='client hub created: %s' % str(address))
187
188
  else:
188
189
  # server
@@ -191,7 +192,8 @@ class GateKeeper(Runner, DockerDelegate, Logging):
191
192
  if address is None:
192
193
  address = get_remote_address(sock=sock)
193
194
  channel = StreamChannel(remote=address, local=get_local_address(sock=sock))
194
- Runner.async_run(coroutine=channel.set_socket(sock=sock))
195
+ coro = channel.set_socket(sock=sock)
196
+ Runner.async_task(coro=coro)
195
197
  hub = StreamServerHub(delegate=delegate)
196
198
  hub.put_channel(channel=channel)
197
199
  return hub
@@ -112,10 +112,10 @@ class MessageQueue:
112
112
  self.__insert(priority=priority)
113
113
  else:
114
114
  # 1.3. check duplicated
115
- signature = msg.get('signature')
116
115
  for wrapper in fleet:
117
116
  item = wrapper.msg
118
117
  if self.__is_duplicated(item, msg):
118
+ signature = msg.get('signature')
119
119
  print('[QUEUE] duplicated message: %s' % signature)
120
120
  return False
121
121
  # 2. append with wrapper
@@ -87,7 +87,9 @@ class BaseSession(GateKeeper, Session, ABC):
87
87
  # Override
88
88
  async def queue_message_package(self, msg: ReliableMessage, data: bytes, priority: int = 0) -> bool:
89
89
  ship = await self._docker_pack(payload=data, priority=priority)
90
- if ship is not None:
90
+ if ship is None:
91
+ self.error(msg='failed to pack msg: %s -> %s, %s' % (msg.sender, msg.receiver, msg.group))
92
+ else:
91
93
  return self._queue_append(msg=msg, ship=ship)
92
94
 
93
95
  #
@@ -33,7 +33,7 @@ import threading
33
33
  from typing import Optional, List, Tuple
34
34
 
35
35
  from startrek.types import SocketAddress
36
- from startrek.fsm import Runner
36
+ from startrek.skywalker import Runner
37
37
  from startrek import Arrival, Departure
38
38
  from startrek import ArrivalShip, DepartureShip, DeparturePriority
39
39
  from startrek import BaseConnection, BaseChannel
@@ -164,7 +164,8 @@ class WSDocker(PlainDocker, DeparturePacker):
164
164
  res = WebSocket.handshake(stream=data)
165
165
  if res is not None:
166
166
  ship = WSDeparture(package=res, payload=b'')
167
- Runner.async_run(coroutine=self.send_ship(ship=ship))
167
+ coro = self.send_ship(ship=ship)
168
+ Runner.async_task(coro=coro)
168
169
  self.__handshaking = False
169
170
  elif len(data) < self.MAX_PACK_LENGTH:
170
171
  # waiting for more data
@@ -41,7 +41,7 @@ from dimsdk import ReliableMessage
41
41
  from dimsdk import Station
42
42
 
43
43
  from ..utils import Log, Logging
44
- from ..utils import Runner, DaemonRunner
44
+ from ..utils import Runner
45
45
  from ..utils import get_msg_sig
46
46
  from ..common import ProviderInfo
47
47
  from ..common import MessageDBI, SessionDBI
@@ -58,7 +58,7 @@ from .shared import GlobalVariable
58
58
  from .shared import create_session
59
59
 
60
60
 
61
- class Octopus(DaemonRunner, Logging):
61
+ class Octopus(Runner, Logging):
62
62
 
63
63
  def __init__(self, shared: GlobalVariable, local_host: str = '127.0.0.1', local_port: int = 9394):
64
64
  super().__init__(interval=60)
@@ -142,6 +142,14 @@ class Octopus(DaemonRunner, Logging):
142
142
  # 3. stop runner
143
143
  await super().stop()
144
144
 
145
+ # Override
146
+ async def setup(self):
147
+ pass
148
+
149
+ # Override
150
+ async def finish(self):
151
+ pass
152
+
145
153
  # Override
146
154
  async def process(self) -> bool:
147
155
  # get all neighbor stations
@@ -380,7 +388,7 @@ def create_messenger(facebook: ClientFacebook, database: MessageDBI,
380
388
  def create_terminal(messenger: OctopusMessenger) -> Terminal:
381
389
  terminal = Terminal(messenger=messenger)
382
390
  messenger.terminal = terminal
383
- Runner.thread_run(terminal)
391
+ Runner.thread_run(runner=terminal)
384
392
  return terminal
385
393
 
386
394
 
@@ -75,8 +75,7 @@ async def main():
75
75
  assert host is not None and port > 0, 'station config error: %s' % config
76
76
  octopus = Octopus(shared=shared, local_host=host, local_port=port)
77
77
  await octopus.start()
78
- while octopus.running:
79
- await Runner.sleep(seconds=1.0)
78
+ await octopus.run()
80
79
  Log.warning(msg='bot stopped: %s' % octopus)
81
80
 
82
81
 
@@ -61,7 +61,7 @@ class GroupCommandHelper(Logging):
61
61
  #
62
62
 
63
63
  async def save_group_history(self, group: ID, content: GroupCommand, message: ReliableMessage) -> bool:
64
- if self.is_expired(content=content):
64
+ if await self.is_expired(content=content):
65
65
  self.warning(msg='drop expired command: %s, %s => %s' % (content.cmd, message.sender, group))
66
66
  return False
67
67
  # check command time
@@ -114,6 +114,7 @@ class GroupCommandHelper(Logging):
114
114
  # membership command, check with reset command
115
115
  cmd, _ = await self.get_reset_command_message(group=group)
116
116
  if cmd is None: # or msg is None:
117
+ self.error(msg='"reset" command not found: %s' % content)
117
118
  return False
118
119
  return is_before(old_time=cmd.time, new_time=content.time)
119
120
 
@@ -39,7 +39,7 @@ from dimsdk import Station
39
39
  from dimsdk import Content, ReceiptCommand
40
40
  from dimsdk import ReliableMessage
41
41
 
42
- from ..utils import Singleton, Log, Logging, Runner, DaemonRunner
42
+ from ..utils import Singleton, Log, Logging, Runner
43
43
  from ..common import CommonFacebook
44
44
  from ..common import MessageDBI, SessionDBI
45
45
  from ..common import ReliableMessageDBI
@@ -133,8 +133,8 @@ class Dispatcher(MessageDeliver, Logging):
133
133
  assert db is not None, 'dispatcher not initialized'
134
134
  runner = Roamer(database=db)
135
135
  self.__roamer = runner
136
- # Runner.async_run(coroutine=runner.start())
137
- Runner.thread_run(runner)
136
+ # Runner.async_task(coro=runner.start())
137
+ Runner.thread_run(runner=runner)
138
138
  return runner
139
139
 
140
140
  def add_roaming(self, user: ID, station: ID) -> bool:
@@ -275,7 +275,7 @@ class RoamingInfo:
275
275
  self.station = station
276
276
 
277
277
 
278
- class Roamer(DaemonRunner, Logging):
278
+ class Roamer(Runner, Logging):
279
279
  """ Delegate for redirect cached messages to roamed station """
280
280
 
281
281
  def __init__(self, database: MessageDBI):
@@ -310,6 +310,14 @@ class Roamer(DaemonRunner, Logging):
310
310
  self.__append(info=info)
311
311
  return True
312
312
 
313
+ # Override
314
+ async def setup(self):
315
+ pass
316
+
317
+ # Override
318
+ async def finish(self):
319
+ pass
320
+
313
321
  # Override
314
322
  async def process(self) -> bool:
315
323
  info = self.__next()
@@ -143,6 +143,8 @@ class MuteFilter(Logging):
143
143
  """ Filter for Push Notification service """
144
144
 
145
145
  async def is_muted(self, msg: ReliableMessage) -> bool:
146
+ if msg.get_bool(key='muted', default=False):
147
+ return True
146
148
  sender = msg.sender
147
149
  receiver = msg.receiver
148
150
  group = msg.group
@@ -152,7 +154,7 @@ class MuteFilter(Logging):
152
154
  return True
153
155
  elif sender.type == EntityType.BOT:
154
156
  # mute group message from bot
155
- return group is not None or receiver.is_group
157
+ return receiver.is_group or group is not None or 'GF' in msg
156
158
  elif receiver.type == EntityType.BOT:
157
159
  # mute all messages to bots
158
160
  return True
@@ -38,7 +38,7 @@ from typing import Optional, List, Dict
38
38
 
39
39
  from dimsdk import ID, ReliableMessage
40
40
 
41
- from ..utils import Runner, DaemonRunner
41
+ from ..utils import Runner
42
42
  from ..utils import Singleton, Logging
43
43
 
44
44
 
@@ -117,15 +117,15 @@ class PushService(ABC):
117
117
 
118
118
 
119
119
  @Singleton
120
- class PushCenter(DaemonRunner, Logging):
120
+ class PushCenter(Runner, Logging):
121
121
 
122
122
  def __init__(self):
123
123
  super().__init__(interval=Runner.INTERVAL_SLOW)
124
124
  self.__queue = MessageQueue()
125
125
  self.__keeper = BadgeKeeper()
126
126
  self.__service: Optional[PushService] = None
127
- # Runner.async_run(coroutine=self.start())
128
- Runner.thread_run(self)
127
+ # Runner.async_task(coro=self.start())
128
+ Runner.thread_run(runner=self)
129
129
 
130
130
  @property
131
131
  def service(self) -> Optional[PushService]:
@@ -149,6 +149,14 @@ class PushCenter(DaemonRunner, Logging):
149
149
  queue = self.__queue
150
150
  queue.add_message(msg=msg)
151
151
 
152
+ # Override
153
+ async def setup(self):
154
+ pass
155
+
156
+ # Override
157
+ async def finish(self):
158
+ pass
159
+
152
160
  # Override
153
161
  async def process(self) -> bool:
154
162
  # 1. get waiting messages
@@ -95,9 +95,8 @@ class ServerSession(BaseSession):
95
95
  if super().set_identifier(identifier=identifier):
96
96
  session_change_id(session=self, new_id=identifier, old_id=old)
97
97
  # load cached message asynchronously
98
- crt = load_cached_messages(session=self)
99
- # Runner.async_run(coroutine=crt)
100
- Runner.thread_run(crt)
98
+ coro = load_cached_messages(session=self)
99
+ Runner.async_task(coro=coro)
101
100
  return True
102
101
 
103
102
  # Override
@@ -105,16 +104,10 @@ class ServerSession(BaseSession):
105
104
  if super().set_active(active=active, when=when):
106
105
  session_change_active(session=self, active=active)
107
106
  # load cached message asynchronously
108
- crt = load_cached_messages(session=self)
109
- # Runner.async_run(coroutine=crt)
110
- Runner.thread_run(crt)
107
+ coro = load_cached_messages(session=self)
108
+ Runner.async_task(coro=coro)
111
109
  return True
112
110
 
113
- # Override
114
- async def start(self):
115
- await super().start()
116
- await self.run()
117
-
118
111
  #
119
112
  # Docker Delegate
120
113
  #
@@ -64,14 +64,15 @@ class RequestHandler(StreamRequestHandler, Logging):
64
64
  super().handle()
65
65
  try:
66
66
  self.info(msg='session started: %s' % str(self.client_address))
67
- Runner.sync_run(main=start_session(client_address=self.client_address, request=self.request))
67
+ crt = _start_session(client_address=self.client_address, request=self.request)
68
+ Runner.sync_run(main=crt)
68
69
  self.info(msg='session finished: %s' % str(self.client_address))
69
70
  except Exception as error:
70
71
  self.error(msg='request handler error: %s' % error)
71
72
  traceback.print_exc()
72
73
 
73
74
 
74
- async def start_session(client_address, request):
75
+ async def _start_session(client_address, request):
75
76
  shared = GlobalVariable()
76
77
  session = ServerSession(remote=client_address, sock=request, database=shared.sdb)
77
78
  messenger = create_messenger(facebook=shared.facebook, database=shared.mdb, session=session)
@@ -81,6 +82,8 @@ async def start_session(client_address, request):
81
82
  try:
82
83
  # handle
83
84
  await session.start()
85
+ await session.run()
86
+ # await session.stop()
84
87
  finally:
85
88
  # finish
86
89
  center.remove_session(session=session)
@@ -33,7 +33,6 @@
33
33
  -- Albert Moky @ Jan. 23, 2019
34
34
  """
35
35
 
36
- import threading
37
36
  from typing import Optional, List, Dict
38
37
 
39
38
  from dimsdk import md5, sha1, sha256, keccak256, ripemd160
@@ -51,12 +50,12 @@ from dimsdk import DocumentHelper
51
50
 
52
51
  from dimplugins.crypto.aes import random_bytes
53
52
 
54
- from startrek.fsm import Singleton
55
- from startrek.fsm import Runnable, Runner, Daemon, DaemonRunner
53
+ from startrek.skywalker import Singleton
54
+ from startrek.skywalker import Runnable, Daemon
56
55
  from startrek.fsm import Delegate as StateDelegate
57
- from startrek.net.channel import get_remote_address, get_local_address
58
-
56
+ from startrek.net.socket import get_remote_address, get_local_address
59
57
 
58
+ from .runner import PatchRunner as Runner
60
59
  from .log import Log, Logging
61
60
  from .dos import Path, File, TextFile, JSONFile
62
61
  from .cache import CachePool, CacheHolder, CacheManager
@@ -123,7 +122,7 @@ __all__ = [
123
122
 
124
123
  'Converter',
125
124
 
126
- 'Runnable', 'Runner', 'Daemon', 'DaemonRunner',
125
+ 'Runnable', 'Runner', 'Daemon',
127
126
  'StateDelegate',
128
127
 
129
128
  'get_remote_address', 'get_local_address',
@@ -143,37 +142,3 @@ __all__ = [
143
142
  'template_replace',
144
143
 
145
144
  ]
146
-
147
-
148
- #
149
- # Patch for Runner
150
- #
151
- async def _run_forever(runner: Runner):
152
- await runner.start()
153
- while True:
154
- await Runner.sleep(seconds=2.0)
155
- if not runner.running:
156
- break
157
- Log.warning(msg='runner stopped: %s' % runner)
158
-
159
-
160
- def _start_runner(runner: Runner):
161
- Runner.sync_run(main=_run_forever(runner=runner))
162
-
163
-
164
- def _start_coroutine(coroutine):
165
- Runner.sync_run(main=coroutine)
166
-
167
-
168
- def _bg_run(target):
169
- if isinstance(target, Runner):
170
- fn = _start_runner
171
- else:
172
- fn = _start_coroutine
173
- thr = threading.Thread(target=fn, args=(target,), daemon=True)
174
- thr.start()
175
- return thr
176
-
177
-
178
- """ Run coroutine in background thread """
179
- Runner.thread_run = _bg_run
@@ -31,10 +31,12 @@
31
31
 
32
32
  from typing import TypeVar, Generic, Optional, Dict, Set, Tuple
33
33
 
34
- from startrek.fsm import Singleton
35
- from startrek.fsm import Runnable, Runner, Daemon
34
+ from startrek.skywalker import Singleton
36
35
  from dimsdk import DateTime
37
36
 
37
+ from .runner import PatchRunner as Runner
38
+ from .log import Logging
39
+
38
40
 
39
41
  K = TypeVar('K')
40
42
  V = TypeVar('V')
@@ -133,44 +135,37 @@ class CachePool(Generic[K, V]):
133
135
 
134
136
 
135
137
  @Singleton
136
- class CacheManager(Runnable):
138
+ class CacheManager(Runner, Logging):
137
139
 
138
140
  def __init__(self):
141
+ super().__init__(interval=2.0)
139
142
  self.__pools: Dict[str, CachePool] = {} # name -> pool
140
- # thread for cleaning caches
141
- self.__running = True
142
- self.__daemon = Daemon(target=self)
143
- self.__daemon.start()
143
+ self.__next_time = DateTime.now()
144
+ # Runner.async_task(coro=self.start())
145
+ Runner.thread_run(runner=self)
144
146
 
145
- @property
146
- def running(self) -> bool:
147
- return self.__running
147
+ # Override
148
+ async def setup(self):
149
+ pass
148
150
 
149
- async def stop(self):
150
- # 1. mark this gate to stopped
151
- self.__running = False
152
- # 2. waiting for the gate to stop
153
- await Runner.sleep(seconds=5)
154
- # 3. cancel the async task
155
- self.__daemon.stop()
151
+ # Override
152
+ async def finish(self):
153
+ pass
156
154
 
157
155
  # Override
158
- async def run(self):
159
- next_time = 0
160
- while self.running:
161
- # try to purge each 5 minutes
162
- now = DateTime.now()
163
- if now < next_time:
164
- await Runner.sleep(seconds=2)
165
- continue
166
- else:
167
- next_time = DateTime(now.timestamp + 300)
168
- try:
169
- count = self.purge(now=now)
170
- print('[MEM] purge %d item(s) from cache pools' % count)
171
- except Exception as error:
172
- print('[MEM] failed to purge cache: %s' % error)
173
- print('[MEM] stop %s' % self)
156
+ async def process(self) -> bool:
157
+ # try to purge each 5 minutes
158
+ now = DateTime.now()
159
+ if now < self.__next_time:
160
+ return False
161
+ else:
162
+ self.__next_time = DateTime(now.timestamp + 300)
163
+ # purge
164
+ try:
165
+ count = self.purge(now=now)
166
+ self.info(msg='[MEM] purge %d item(s) from cache pools' % count)
167
+ except Exception as error:
168
+ self.error(msg='[MEM] failed to purge cache: %s' % error)
174
169
 
175
170
  def get_pool(self, name: str) -> CachePool[K, V]:
176
171
  """ get pool with name """
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from threading import Thread
4
+
5
+ from startrek.skywalker import Runner
6
+
7
+
8
+ # noinspection PyAbstractClass
9
+ class PatchRunner(Runner):
10
+
11
+ @classmethod
12
+ def thread_run(cls, runner: Runner) -> Thread:
13
+ thr = Runner.async_thread(coro=_bg_runner(runner=runner))
14
+ thr.start()
15
+ return thr
16
+
17
+
18
+ async def _bg_runner(runner: Runner):
19
+ await runner.start()
20
+ await runner.run()
21
+
22
+
23
+ # Patch for Runner
24
+ Runner.thread_run = PatchRunner.thread_run
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dimples
3
- Version: 1.1.0
3
+ Version: 1.2.1
4
4
  Summary: DIMP Library for Edges and Stations
5
5
  Home-page: https://github.com/dimchat/demo-py
6
6
  Author: Albert Moky
@@ -138,4 +138,5 @@ dimples/utils/__init__.py
138
138
  dimples/utils/cache.py
139
139
  dimples/utils/config.py
140
140
  dimples/utils/dos.py
141
- dimples/utils/log.py
141
+ dimples/utils/log.py
142
+ dimples/utils/runner.py
@@ -3,6 +3,6 @@ dimsdk>=2.0.0
3
3
  dimp>=2.0.0
4
4
  dkd>=2.0.0
5
5
  mkm>=2.0.0
6
- startrek>=2.0.0
7
- tcp>=2.0.0
8
- udp>=2.0.0
6
+ startrek>=2.1.1
7
+ tcp>=2.1.1
8
+ udp>=2.1.1
@@ -14,7 +14,7 @@ import io
14
14
 
15
15
  from setuptools import setup, find_packages
16
16
 
17
- __version__ = '1.1.0'
17
+ __version__ = '1.2.1'
18
18
  __author__ = 'Albert Moky'
19
19
  __contact__ = 'albert.moky@gmail.com'
20
20
 
@@ -58,8 +58,8 @@ setup(
58
58
  'dkd>=2.0.0',
59
59
  'mkm>=2.0.0',
60
60
 
61
- 'startrek>=2.0.0',
62
- 'tcp>=2.0.0',
63
- 'udp>=2.0.0',
61
+ 'startrek>=2.1.1',
62
+ 'tcp>=2.1.1',
63
+ 'udp>=2.1.1',
64
64
  ]
65
65
  )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes