devservices 1.2.3__tar.gz → 1.2.4__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 (68) hide show
  1. {devservices-1.2.3 → devservices-1.2.4}/PKG-INFO +1 -1
  2. {devservices-1.2.3 → devservices-1.2.4}/README.md +1 -1
  3. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/supervisor.py +31 -1
  4. {devservices-1.2.3 → devservices-1.2.4}/devservices.egg-info/PKG-INFO +1 -1
  5. {devservices-1.2.3 → devservices-1.2.4}/pyproject.toml +1 -1
  6. {devservices-1.2.3 → devservices-1.2.4}/LICENSE.md +0 -0
  7. {devservices-1.2.3 → devservices-1.2.4}/devservices/__init__.py +0 -0
  8. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/__init__.py +0 -0
  9. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/down.py +0 -0
  10. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/foreground.py +0 -0
  11. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/list_dependencies.py +0 -0
  12. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/list_services.py +0 -0
  13. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/logs.py +0 -0
  14. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/purge.py +0 -0
  15. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/reset.py +0 -0
  16. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/serve.py +0 -0
  17. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/status.py +0 -0
  18. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/toggle.py +0 -0
  19. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/up.py +0 -0
  20. {devservices-1.2.3 → devservices-1.2.4}/devservices/commands/update.py +0 -0
  21. {devservices-1.2.3 → devservices-1.2.4}/devservices/configs/service_config.py +0 -0
  22. {devservices-1.2.3 → devservices-1.2.4}/devservices/constants.py +0 -0
  23. {devservices-1.2.3 → devservices-1.2.4}/devservices/exceptions.py +0 -0
  24. {devservices-1.2.3 → devservices-1.2.4}/devservices/main.py +0 -0
  25. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/__init__.py +0 -0
  26. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/check_for_update.py +0 -0
  27. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/console.py +0 -0
  28. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/dependencies.py +0 -0
  29. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/devenv.py +0 -0
  30. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/docker.py +0 -0
  31. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/docker_compose.py +0 -0
  32. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/file_lock.py +0 -0
  33. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/git.py +0 -0
  34. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/install_binary.py +0 -0
  35. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/services.py +0 -0
  36. {devservices-1.2.3 → devservices-1.2.4}/devservices/utils/state.py +0 -0
  37. {devservices-1.2.3 → devservices-1.2.4}/devservices.egg-info/SOURCES.txt +0 -0
  38. {devservices-1.2.3 → devservices-1.2.4}/devservices.egg-info/dependency_links.txt +0 -0
  39. {devservices-1.2.3 → devservices-1.2.4}/devservices.egg-info/entry_points.txt +0 -0
  40. {devservices-1.2.3 → devservices-1.2.4}/devservices.egg-info/requires.txt +0 -0
  41. {devservices-1.2.3 → devservices-1.2.4}/devservices.egg-info/top_level.txt +0 -0
  42. {devservices-1.2.3 → devservices-1.2.4}/setup.cfg +0 -0
  43. {devservices-1.2.3 → devservices-1.2.4}/testing/__init__.py +0 -0
  44. {devservices-1.2.3 → devservices-1.2.4}/testing/utils.py +0 -0
  45. {devservices-1.2.3 → devservices-1.2.4}/tests/__init__.py +0 -0
  46. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_down.py +0 -0
  47. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_foreground.py +0 -0
  48. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_list_dependencies.py +0 -0
  49. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_list_services.py +0 -0
  50. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_logs.py +0 -0
  51. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_purge.py +0 -0
  52. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_reset.py +0 -0
  53. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_serve.py +0 -0
  54. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_status.py +0 -0
  55. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_toggle.py +0 -0
  56. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_up.py +0 -0
  57. {devservices-1.2.3 → devservices-1.2.4}/tests/commands/test_update.py +0 -0
  58. {devservices-1.2.3 → devservices-1.2.4}/tests/configs/test_service_config.py +0 -0
  59. {devservices-1.2.3 → devservices-1.2.4}/tests/conftest.py +0 -0
  60. {devservices-1.2.3 → devservices-1.2.4}/tests/utils/test_check_for_update.py +0 -0
  61. {devservices-1.2.3 → devservices-1.2.4}/tests/utils/test_dependencies.py +0 -0
  62. {devservices-1.2.3 → devservices-1.2.4}/tests/utils/test_docker.py +0 -0
  63. {devservices-1.2.3 → devservices-1.2.4}/tests/utils/test_docker_compose.py +0 -0
  64. {devservices-1.2.3 → devservices-1.2.4}/tests/utils/test_git.py +0 -0
  65. {devservices-1.2.3 → devservices-1.2.4}/tests/utils/test_install_binary.py +0 -0
  66. {devservices-1.2.3 → devservices-1.2.4}/tests/utils/test_services.py +0 -0
  67. {devservices-1.2.3 → devservices-1.2.4}/tests/utils/test_state.py +0 -0
  68. {devservices-1.2.3 → devservices-1.2.4}/tests/utils/test_supervisor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devservices
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Requires-Python: >=3.11
5
5
  License-File: LICENSE.md
6
6
  Requires-Dist: pyyaml
@@ -33,7 +33,7 @@ NOTE: service-name is an optional parameter. If not provided, devservices will a
33
33
  The recommended way to install devservices is through a virtualenv in the requirements.txt. Once that is installed and a devservices config file is added, you should be able to run `devservices up` to begin local development.
34
34
 
35
35
  ```
36
- devservices==1.2.3
36
+ devservices==1.2.4
37
37
  ```
38
38
 
39
39
  ### 2. Add devservices config files
@@ -53,6 +53,17 @@ class SupervisorDaemonState(IntEnum):
53
53
  SHUTDOWN = -1
54
54
 
55
55
 
56
+ class SupervisorFaultCode(IntEnum):
57
+ """
58
+ Supervisor XML-RPC fault codes.
59
+
60
+ https://supervisord.org/api.html#xml-rpc-api-documentation
61
+ """
62
+
63
+ ALREADY_STARTED = 60
64
+ NOT_RUNNING = 70
65
+
66
+
56
67
  class UnixSocketHTTPConnection(http.client.HTTPConnection):
57
68
  """HTTP connection over Unix sockets."""
58
69
 
@@ -222,7 +233,12 @@ class SupervisorManager:
222
233
  if not isinstance(state, int):
223
234
  return False
224
235
  return state == SupervisorProcessState.RUNNING
225
- except xmlrpc.client.Fault:
236
+ except (
237
+ xmlrpc.client.Fault,
238
+ SupervisorConnectionError,
239
+ socket.error,
240
+ ConnectionRefusedError,
241
+ ):
226
242
  # If we can't get the process info, assume it's not running
227
243
  return False
228
244
 
@@ -295,6 +311,9 @@ class SupervisorManager:
295
311
  self._get_rpc_client().supervisor.shutdown()
296
312
  except xmlrpc.client.Fault as e:
297
313
  raise SupervisorError(f"Failed to stop supervisor: {e.faultString}")
314
+ except (SupervisorConnectionError, socket.error, ConnectionRefusedError):
315
+ # Supervisor is already down, nothing to do
316
+ pass
298
317
 
299
318
  def start_process(self, name: str) -> None:
300
319
  if self._is_program_running(name):
@@ -302,6 +321,10 @@ class SupervisorManager:
302
321
  try:
303
322
  self._get_rpc_client().supervisor.startProcess(name)
304
323
  except xmlrpc.client.Fault as e:
324
+ # ALREADY_STARTED is acceptable in concurrent scenarios
325
+ # where multiple threads may attempt to start the same process
326
+ if e.faultCode == SupervisorFaultCode.ALREADY_STARTED:
327
+ return
305
328
  raise SupervisorProcessError(
306
329
  f"Failed to start process {name}: {e.faultString}"
307
330
  )
@@ -312,9 +335,16 @@ class SupervisorManager:
312
335
  try:
313
336
  self._get_rpc_client().supervisor.stopProcess(name)
314
337
  except xmlrpc.client.Fault as e:
338
+ # NOT_RUNNING is acceptable in concurrent scenarios
339
+ # where multiple threads may attempt to stop the same process
340
+ if e.faultCode == SupervisorFaultCode.NOT_RUNNING:
341
+ return
315
342
  raise SupervisorProcessError(
316
343
  f"Failed to stop process {name}: {e.faultString}"
317
344
  )
345
+ except (SupervisorConnectionError, socket.error, ConnectionRefusedError):
346
+ # Supervisor is not available, process is already stopped
347
+ pass
318
348
 
319
349
  def get_program_command(self, program_name: str) -> str:
320
350
  opts = ServerOptions()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devservices
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Requires-Python: >=3.11
5
5
  License-File: LICENSE.md
6
6
  Requires-Dist: pyyaml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devservices"
7
- version = "1.2.3"
7
+ version = "1.2.4"
8
8
  # 3.11 is just for internal pypi compat
9
9
  requires-python = ">=3.11"
10
10
  dependencies = [
File without changes
File without changes