swisseph 1.4.0 → 1.4.1

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 (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -0
  3. data/lib/swisseph.rb +26 -0
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f9d37403571721f14d42714107574eb2476931241eb06a45bbdb0c366366cf4
4
- data.tar.gz: f9fa581bfdf33d06aced3552233bbe5eedbdb37b3fa27a96ddcac7a8bab4fc62
3
+ metadata.gz: d3bd5d41ff56c59145864cde33f26a5cf624b821f12261b45bf6c6c32aa0006b
4
+ data.tar.gz: b0c23352d9117a5f89b72b02c72785e6ab30e768552a52161363ad98ac53bfd5
5
5
  SHA512:
6
- metadata.gz: 5a916c629960dac6c5ce97ea5a3c885986ef299949c7a574b300ebfd04a0fec4825b99c4dfa263eb8b6cf2400fdadd071a8219aef5aa206988205f41bd059197
7
- data.tar.gz: 91ba4396d1fe0f165ea78789371ff2507a842d16c703ce8bacd04d60416472db175341a55e42dfc3e2f0e263e21ae609e3d0918609cd1a3c270f9da6df4a5fc9
6
+ metadata.gz: 1691fd37c14307225d04365279d8f0ba96b4cd95e9ed6ca4ec769bcb8c9a350238f00f9d68084fd0c1a9ad0347022cdb721b08abbfb71100645e1a372def5b8e
7
+ data.tar.gz: 75dce6e93170c127ecb97eb57660357046864128ede073e13913c97dba0b3357cad69ebd428d39fecd3c60efe01de696ab02b63c6c3a19938c4a159f2cc164a5
data/README.md CHANGED
@@ -35,6 +35,16 @@ For even shorter code, you can use the `Sweph` alias:
35
35
  Sweph.julday(2024, 1, 1, 12.0)
36
36
  ```
37
37
 
38
+ ### Thread Safety
39
+ The underlying Swiss Ephemeris C library keeps process-global state and a shared
40
+ data-file descriptor, so it is **not thread-safe** -- two threads inside it at
41
+ once can segfault the process. Every native call (and its shorthand alias) is
42
+ serialized through one global re-entrant lock, `Swisseph::LOCK`, so the bindings
43
+ are safe to call from multi-threaded hosts (e.g. a threaded Puma app with
44
+ in-process background workers). A single-threaded caller never waits for the
45
+ lock; when multiple threads call concurrently they are serialized (a brief wait,
46
+ far cheaper than the crash it prevents).
47
+
38
48
  ---
39
49
 
40
50
  ## Installation
data/lib/swisseph.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'monitor'
3
4
  require 'swisseph/swisseph'
4
5
 
5
6
  # Shorthand alias
@@ -14,3 +15,28 @@ module Swisseph
14
15
  define_singleton_method(alias_name, method(method_name)) unless respond_to?(alias_name)
15
16
  end
16
17
  end
18
+
19
+ module Swisseph
20
+ # The Swiss Ephemeris C library (libswe) keeps process-global state and a
21
+ # shared file descriptor for its data files, so it is NOT thread-safe: two
22
+ # threads executing inside it at once can segfault the process. Every native
23
+ # call is serialized through one global re-entrant lock so concurrent threads
24
+ # -- e.g. a multi-threaded Puma app plus in-process background workers --
25
+ # can never be inside libswe simultaneously. A single-threaded caller never
26
+ # contends for the lock; concurrent callers are serialized (a brief wait, not
27
+ # a segfault).
28
+ LOCK = Monitor.new
29
+ end
30
+
31
+ # Wrap every current singleton method (the native swe_* methods and the
32
+ # shorthand aliases defined above) so each public entry point takes the lock.
33
+ Swisseph.singleton_class.prepend(
34
+ Module.new do
35
+ lock = Swisseph::LOCK
36
+ Swisseph.singleton_methods(false).each do |name|
37
+ define_method(name) do |*args, &block|
38
+ lock.synchronize { super(*args, &block) }
39
+ end
40
+ end
41
+ end
42
+ )
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swisseph
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Lowenfels
@@ -116,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  requirements: []
119
- rubygems_version: 3.6.2
119
+ rubygems_version: 4.0.3
120
120
  specification_version: 4
121
121
  summary: Swiss Ephemeris for Ruby (astrology)
122
122
  test_files: []