activecypher 0.12.1 → 0.12.2

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: 43840a1c50c381abdd55b077b1748b8b06f6bd360cea489c70f46bb2da54735a
4
- data.tar.gz: 4a06216a9511ca7c5f25b509a742aa91d701c634cd1778f7feecdba9ee948492
3
+ metadata.gz: 29fa2252b85c3c67d4f8a8e72acc69ad1021088561ce02c8e1d205bef28b4069
4
+ data.tar.gz: 0665ef0b5e7a68264f50b846ba78036dc5d3c805e874bc475abb12a3bb699069
5
5
  SHA512:
6
- metadata.gz: a3aeb03225c68a06e1a085ddef27f89d51e3084b86ddce90111754ab619a70f73e082eba8f1f7b80a9b8d2a1b6e297ff403d47f79e3877487cfbcb86fec322c2
7
- data.tar.gz: 635b65a8fa3eb23e6758aaaa9fe51390ebce7e92b442710bffd672865b3767663aa4b02de768fca692db6d9e247ba8a80b2036d2a8c0639a06d815eeddc5439b
6
+ metadata.gz: 13b575ead30e4ea3b3476e97993c33e8eebc2dfb788d10e7ad9aa8e02014f389581d3e619f50629611340ea33af2bae967b026cd07110de57586887919ff89f3
7
+ data.tar.gz: a9dd762af2674169b558739ca5652e21cfcb60adb8a491c5d0bdf22b64a19b45c1087858db972a71f26af9113ee146e67ef57188e6f273adef959ca369a407d3
@@ -485,15 +485,6 @@ module ActiveCypher
485
485
  session(database: db).write_transaction(db: db, timeout: timeout, metadata: metadata, &)
486
486
  end
487
487
 
488
- # Asynchronously execute a read transaction.
489
- def async_read_transaction(db: nil, timeout: nil, metadata: nil, &)
490
- session(database: db).async_read_transaction(db: db, timeout: timeout, metadata: metadata, &)
491
- end
492
-
493
- # Asynchronously execute a write transaction.
494
- def async_write_transaction(db: nil, timeout: nil, metadata: nil, &)
495
- session(database: db).async_write_transaction(db: db, timeout: timeout, metadata: metadata, &)
496
- end
497
488
 
498
489
  # ────────────────────────────────────────────────────────────────────
499
490
  # HEALTH AND VERSION DETECTION METHODS
@@ -40,19 +40,9 @@ module ActiveCypher
40
40
  #
41
41
  # @yieldparam session [Bolt::Session] The session to use
42
42
  # @return [Object] The result of the block
43
- def with_session(**kw)
43
+ def with_session(**kw, &block)
44
44
  Sync do
45
- @pool.acquire do |conn|
46
- conn.mark_used!
47
- session = Bolt::Session.new(conn, **kw)
48
-
49
- yield session
50
- ensure
51
- # Make sure any open transaction is cleaned up before returning the
52
- # connection to the pool, so the next borrower doesn't inherit
53
- # IN_TRANSACTION state.
54
- session&.close
55
- end
45
+ _acquire_session(**kw, &block)
56
46
  end
57
47
  rescue Async::TimeoutError => e
58
48
  raise ActiveCypher::ConnectionError, "Connection pool timeout: #{e.message}"
@@ -60,6 +50,19 @@ module ActiveCypher
60
50
  raise ActiveCypher::ConnectionError, "Connection error: #{e.message}"
61
51
  end
62
52
 
53
+ # Asynchronously yields a Session. Each call acquires its own connection from the pool,
54
+ # making it safe for concurrent use across fibers.
55
+ #
56
+ # @yieldparam session [Bolt::Session] The session to use
57
+ # @return [Async::Task] A task that resolves to the block's result
58
+ def async_with_session(**kw, &block)
59
+ raise 'Cannot run async_with_session outside of an Async task' unless Async::Task.current?
60
+
61
+ Async do
62
+ _acquire_session(**kw, &block)
63
+ end
64
+ end
65
+
63
66
  # Checks if the database is alive, or just faking it for your benefit.
64
67
  #
65
68
  # @return [Boolean]
@@ -78,6 +81,25 @@ module ActiveCypher
78
81
 
79
82
  private
80
83
 
84
+ # Internal: acquires a connection and yields a session.
85
+ # @yieldparam session [Bolt::Session]
86
+ # @return [Object] The result of the block
87
+ def _acquire_session(**kw)
88
+ @pool.acquire do |conn|
89
+ conn.mark_used!
90
+ session = Bolt::Session.new(conn, **kw)
91
+
92
+ begin
93
+ yield session
94
+ ensure
95
+ # Make sure any open transaction is cleaned up before returning the
96
+ # connection to the pool, so the next borrower doesn't inherit
97
+ # IN_TRANSACTION state.
98
+ session&.close
99
+ end
100
+ end
101
+ end
102
+
81
103
  # Builds a new connection, because the old one just wasn't good enough.
82
104
  #
83
105
  # @return [Connection]
@@ -11,11 +11,12 @@ module ActiveCypher
11
11
  class AbstractBoltAdapter < AbstractAdapter
12
12
  include Instrumentation
13
13
 
14
- attr_reader :connection
14
+ attr_reader :connection, :driver
15
15
 
16
16
  # Returns the raw Bolt connection object
17
17
  # This is useful for accessing low-level connection methods like
18
- # read_transaction, write_transaction, async_read_transaction, etc.
18
+ # read_transaction, write_transaction, etc.
19
+ # NOTE: For concurrent async operations, use with_session or async_with_session instead.
19
20
  def raw_connection
20
21
  @connection
21
22
  end
@@ -54,6 +55,18 @@ module ActiveCypher
54
55
  }
55
56
  end
56
57
 
58
+ # Create the driver with connection pool for concurrent operations
59
+ @driver = Bolt::Driver.new(
60
+ uri: "bolt://#{host}:#{port}",
61
+ adapter: self,
62
+ auth_token: auth,
63
+ pool_size: config.fetch(:pool_size, 10),
64
+ secure: ssl_params[:secure],
65
+ verify_cert: ssl_params[:verify_cert]
66
+ )
67
+
68
+ # Also create a single connection for backwards compatibility
69
+ # This connection is used for simple synchronous operations
57
70
  @connection = Bolt::Connection.new(
58
71
  host, port, self,
59
72
  auth_token: auth,
@@ -72,12 +85,34 @@ module ActiveCypher
72
85
  # Clean disconnection. Resets the internal state.
73
86
  def disconnect
74
87
  instrument_connection(:disconnect) do
75
- @connection.close if @connection
88
+ @driver&.close
89
+ @driver = nil
90
+ @connection&.close
76
91
  @connection = nil
77
92
  true
78
93
  end
79
94
  end
80
95
 
96
+ # Yields a Session from the connection pool. Safe for concurrent use.
97
+ # Each call acquires its own connection from the pool.
98
+ #
99
+ # @yieldparam session [Bolt::Session] The session to use
100
+ # @return [Object] The result of the block
101
+ def with_session(**kw, &block)
102
+ connect
103
+ @driver.with_session(**kw, &block)
104
+ end
105
+
106
+ # Asynchronously yields a Session from the connection pool.
107
+ # Each call acquires its own connection, making it safe for concurrent fibers.
108
+ #
109
+ # @yieldparam session [Bolt::Session] The session to use
110
+ # @return [Async::Task] A task that resolves to the block's result
111
+ def async_with_session(**kw, &block)
112
+ connect
113
+ @driver.async_with_session(**kw, &block)
114
+ end
115
+
81
116
  # Runs a Cypher query via Bolt session.
82
117
  # Automatically handles connect, logs query, cleans up session. Very adult.
83
118
  def run(cypher, params = {}, context: 'Query', db: nil, access_mode: :write)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveCypher
4
- VERSION = '0.12.1'
4
+ VERSION = '0.12.2'
5
5
 
6
6
  def self.gem_version
7
7
  Gem::Version.new VERSION
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activecypher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.1
4
+ version: 0.12.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih
@@ -93,6 +93,20 @@ dependencies:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0.6'
96
+ - !ruby/object:Gem::Dependency
97
+ name: async-safe
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
96
110
  description: OpenCypher Adapter ala ActiveRecord
97
111
  email:
98
112
  - seuros@pre-history.com