virgodb 0.1.4-x86_64-linux-gnu → 0.2.0-x86_64-linux-gnu

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cfde1ca05cc7f6d12cd117d9ff1ec6bd215a5914637f4641b2b01822077357ac
4
- data.tar.gz: 3c51aabe24cf49d04bc8fe1783c1b6533e830f57d1985bcdbc513067f250a4bf
3
+ metadata.gz: b2c55249e7aad1d1fa30b2e5b0b33faeededd48155b6a1d31cad1d66c86f150f
4
+ data.tar.gz: e7f80300627403933ea3dcfb0bc3e8e3321caa3b0f0d11309238978fa65915a0
5
5
  SHA512:
6
- metadata.gz: c43403672c327752e7710e1bdfce3bbca7710d4b20d27f42529ded6272776bd553ec5d40894a2bc53e4e92cf6ba9628eb6a28860b3fdd9e72a6dfb3674f582da
7
- data.tar.gz: 5162de79d2d0979f6677535250c612dd3c1e208266339a8120612fb0ae6a1a6fa8c0fe75ba2aaaf01c2289626d0e83155d41f7f9e24e3c72ed73547a312fad43
6
+ metadata.gz: '00849d11354b21ffa53f665b607aad25114b02f78d296b9b8594016962ea378eb1bdcc905c77d5024e1cf4376b28af183da2c3918d30965bba7f3080547d238e'
7
+ data.tar.gz: b8190d81fdcd7276cf12ead7c054a10e8e61d6f25daa2f39ad42f2166b8118c917cfe031b26cfbfa6239d420ad4ba5ce8e3e8c14b010028c8e8b019871df4d83
data/lib/virgodb/table.rb CHANGED
@@ -11,6 +11,19 @@ module Virgodb
11
11
  # just failing the first write attempt. Mutex-guarded so concurrent
12
12
  # callers in one process can't race to double-initialize.
13
13
  #
14
+ # The SAME mutex also serializes every actual write_row/tombstone/flush!
15
+ # call, not just lazy Writer init -- the underlying Rust Writer wraps a
16
+ # plain RefCell, explicitly documented "not thread-safe by design," so
17
+ # two Ruby threads calling in concurrently would double-borrow it. This
18
+ # is safe today even without a Ruby-level lock, PURELY because none of
19
+ # those three Rust entry points release the GVL (crates/virgodb_ruby/
20
+ # src/writer.rs, tombstone.rs) -- MRI's GVL already fully serializes them.
21
+ # That's an implicit invariant a future perf change could silently break
22
+ # (the read path already got its own GVL-release fix once, see the root
23
+ # README's "Known issues" -- the write path getting the same treatment
24
+ # someday isn't a hypothetical). Locking explicitly here means this
25
+ # class's correctness no longer depends on that invariant holding.
26
+ #
14
27
  # This is the boilerplate every host app embedding virgodb needs around
15
28
  # the raw Writer/start_maintenance/query FFI -- written once here instead
16
29
  # of once per host app. Deliberately does NOT rescue write failures: a
@@ -35,8 +48,18 @@ module Virgodb
35
48
 
36
49
  attr_reader :manifest_path
37
50
 
51
+ # `writer` is called BEFORE entering `@mutex.synchronize` here (and in
52
+ # `tombstone`/`flush!` below), never from inside it -- `writer`'s own
53
+ # lazy-init path takes the SAME mutex when it actually needs to build
54
+ # one, and Ruby's Mutex is not reentrant (a thread re-locking a mutex
55
+ # it already holds raises ThreadError immediately, it doesn't queue).
56
+ # Safe regardless of ordering: `@writer` is assigned at most once and
57
+ # never reassigned afterward, so the reference `writer` returns stays
58
+ # valid and correct for the rest of this object's lifetime no matter
59
+ # what happens between fetching it and entering the lock below.
38
60
  def write_row(**attrs)
39
- writer.write_row(**attrs)
61
+ w = writer
62
+ @mutex.synchronize { w.write_row(**attrs) }
40
63
  end
41
64
 
42
65
  # `tombstone` alone doesn't touch the Writer -- calling `writer` first
@@ -45,19 +68,37 @@ module Virgodb
45
68
  # recorded for it to eventually act on.
46
69
  def tombstone(column:, value:)
47
70
  writer
48
- Virgodb.tombstone(@manifest_path, @sql_table_name, column.to_s, value.to_s)
71
+ @mutex.synchronize { Virgodb.tombstone(@manifest_path, @sql_table_name, column.to_s, value.to_s) }
49
72
  end
50
73
 
51
74
  # Returns parsed JSON rows (Array of String-keyed Hash). `sql` must
52
75
  # refer to the table by its real SQL name (the `sql_table_name` this
53
76
  # instance was built with), not any shorthand a caller's own registry
54
- # might use for it.
77
+ # might use for it. Not mutex-guarded -- a read never touches the
78
+ # Writer's RefCell state at all (Virgodb.query is a separate, already
79
+ # GVL-released, independently-safe-for-concurrency FFI entry point).
55
80
  def query(sql, partition_keys: nil)
56
81
  JSON.parse(Virgodb.query(@manifest_path, @sql_table_name, sql, partition_keys))
57
82
  end
58
83
 
59
84
  def flush!
60
- writer.flush!
85
+ w = writer
86
+ @mutex.synchronize { w.flush! }
87
+ end
88
+
89
+ # This table's current maintenance status (a String-keyed Hash with
90
+ # "holder"/"lease_expires_at"/"last_attempt_at"/"last_success_at"/
91
+ # "last_error"), or nil if maintenance has never even attempted a lease
92
+ # claim yet (e.g. this Table hasn't done its first write, so
93
+ # start_maintenance was never called -- see `ensure_maintenance_started`).
94
+ # A real answer to "is this table's background maintenance actually
95
+ # working," not just "is the thread alive" -- meant to be polled by a
96
+ # host app's own health check, not by this class itself. Not
97
+ # mutex-guarded, same reasoning as `query` above: a read never touches
98
+ # the Writer's RefCell state.
99
+ def maintenance_health
100
+ json = Virgodb.maintenance_health(@manifest_path, @sql_table_name)
101
+ json && JSON.parse(json)
61
102
  end
62
103
 
63
104
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Virgodb
4
- VERSION = "0.1.4"
4
+ VERSION = "0.2.0"
5
5
  end
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: virgodb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: x86_64-linux-gnu
6
6
  authors:
7
7
  - virgodb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-16 00:00:00.000000000 Z
11
+ date: 2026-08-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Embeds virgodb (an OLAP engine backed by Parquet + DataFusion) directly into a Ruby process