grumlin 0.8.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22dad640b5ac86f86381b9bc9fab03989e7b8c42c4b19234efc6b3a223d07055
4
- data.tar.gz: c0cea0f26f1e5a5a9ef1c6ab96335bf24e7f642968030b2b1f1c0a74210898d7
3
+ metadata.gz: 0f0edafd4d46b787eb3f8e0ec4032948bdb4de865e4de3199606fb470dc16ef3
4
+ data.tar.gz: f23ba59dfb18dabe70fc860c38ea4c1777214b4a37e04771b24210d90f449612
5
5
  SHA512:
6
- metadata.gz: 71b7e970733edc7db87736c449008389b47431d41c12382c426b0db348e106047343d279e3d8901d76dd44175478279b4c2e22cd896b690c9d63eedbf605b6ec
7
- data.tar.gz: 82f71e74fb61435de9d6a86fa8cceb4cea32cd8a87f91c6a941bbfbd622a21b67b434f3ccbe298f94265edb9999faa33ea4f80148a56a1e39c6491a575df1ae6
6
+ metadata.gz: 4629a25995953c6617a45721d7082baee59b76425636f6a4536308220bae3e7cb72b571317102339b1888c0e430dbe73320c12f44518940f45c67db829a9a265
7
+ data.tar.gz: fae1a56f95150f82da47a886da5e4b4a7ab0f725f66e68af61f6456c9a2f1af2cefc580ebf793cba612f0ceeda0b782361476a38511019062cc1534ad98fdb3c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grumlin (0.8.0)
4
+ grumlin (0.11.0)
5
5
  async-pool (~> 0.3)
6
6
  async-websocket (~> 0.19)
7
7
  oj (~> 3.12)
@@ -64,7 +64,7 @@ GEM
64
64
  nio4r (2.5.8)
65
65
  nokogiri (1.11.7-x86_64-linux)
66
66
  racc (~> 1.4)
67
- oj (3.13.4)
67
+ oj (3.13.6)
68
68
  overcommit (0.57.0)
69
69
  childprocess (>= 0.6.3, < 5)
70
70
  iniparse (~> 1.4)
@@ -7,7 +7,7 @@ module Grumlin
7
7
  # TODO: add other steps
8
8
  SUPPORTED_STEPS = %w[E V addE addV as by coalesce count dedup drop elementMap emit fold from group groupCount has
9
9
  hasId hasLabel hasNot in inV label limit not order out outE path project property repeat select
10
- to unfold valueMap values where].freeze
10
+ to unfold union valueMap values where].freeze
11
11
 
12
12
  def initialize(name, *args, previous_step: nil)
13
13
  @name = name
@@ -3,7 +3,7 @@
3
3
  module Grumlin
4
4
  # Incapsulates logic of converting step chains and step arguments to queries that can be sent to the server
5
5
  # and to human readable strings.
6
- class Bytecode
6
+ class Bytecode < TypedValue
7
7
  class NoneStep
8
8
  def to_bytecode
9
9
  ["none"]
@@ -13,6 +13,8 @@ module Grumlin
13
13
  NONE_STEP = NoneStep.new
14
14
 
15
15
  def initialize(step, no_return: false)
16
+ super(type: "Bytecode")
17
+
16
18
  @step = step
17
19
  @no_return = no_return
18
20
  end
@@ -22,27 +24,12 @@ module Grumlin
22
24
  end
23
25
  alias to_s inspect
24
26
 
25
- def to_query
26
- {
27
- requestId: SecureRandom.uuid,
28
- op: "bytecode",
29
- processor: "traversal",
30
- args: {
31
- gremlin: to_bytecode,
32
- aliases: { g: :g }
33
- }
34
- }
35
- end
36
-
37
27
  def to_readable_bytecode
38
28
  @to_readable_bytecode ||= steps.map { |s| serialize_arg(s, serialization_method: :to_readable_bytecode) }
39
29
  end
40
30
 
41
- def to_bytecode
42
- @to_bytecode ||= {
43
- "@type": "g:Bytecode",
44
- "@value": { step: (steps + (@no_return ? [NONE_STEP] : [])).map { |s| serialize_arg(s) } }
45
- }
31
+ def value
32
+ { step: (steps + (@no_return ? [NONE_STEP] : [])).map { |s| serialize_arg(s) } }
46
33
  end
47
34
 
48
35
  private
@@ -97,7 +97,7 @@ module Grumlin
97
97
  def write(bytecode)
98
98
  raise NotConnectedError unless connected?
99
99
 
100
- request = bytecode.to_query
100
+ request = to_query(bytecode.to_bytecode)
101
101
  channel = @request_dispatcher.add_request(request)
102
102
  @transport.write(request)
103
103
 
@@ -120,5 +120,17 @@ module Grumlin
120
120
  def build_transport
121
121
  Transport.new(@url, parent: @parent, **@client_options)
122
122
  end
123
+
124
+ def to_query(bytecode)
125
+ {
126
+ requestId: SecureRandom.uuid,
127
+ op: "bytecode",
128
+ processor: "traversal",
129
+ args: {
130
+ gremlin: bytecode,
131
+ aliases: { g: :g }
132
+ }
133
+ }
134
+ end
123
135
  end
124
136
  end
data/lib/grumlin/order.rb CHANGED
@@ -9,7 +9,7 @@ module Grumlin
9
9
  name = "@#{step}"
10
10
  return instance_variable_get(name) if instance_variable_defined?(name)
11
11
 
12
- instance_variable_set(name, TypedValue.new("Order", step))
12
+ instance_variable_set(name, TypedValue.new(type: "Order", value: step))
13
13
  end
14
14
  end
15
15
  end
data/lib/grumlin/p.rb CHANGED
@@ -3,12 +3,40 @@
3
3
  module Grumlin
4
4
  module P
5
5
  module P
6
- %w[within].each do |step|
7
- define_method step do |*args|
8
- { # TODO: replace with a TypedValue?
9
- "@type": "g:P",
10
- "@value": { predicate: "within", value: { "@type": "g:List", "@value": args } }
11
- }
6
+ class Predicate < TypedValue
7
+ def initialize(name, args:, arg_type: nil)
8
+ super(type: "P")
9
+ @name = name
10
+ @args = args
11
+ @arg_type = arg_type
12
+ end
13
+
14
+ def value
15
+ @value ||=
16
+ {
17
+ predicate: @name,
18
+ value: TypedValue.new(type: @arg_type, value: @args).to_bytecode
19
+ }
20
+ end
21
+ end
22
+
23
+ # TODO: support more predicates
24
+ %w[eq neq].each do |predicate|
25
+ define_method predicate do |*args|
26
+ Predicate.new(predicate, args: args[0])
27
+ end
28
+ end
29
+
30
+ %w[within without].each do |predicate|
31
+ define_method predicate do |*args|
32
+ args = if args.count == 1 && args[0].is_a?(Array)
33
+ args[0]
34
+ elsif args.count == 1 && args[0].is_a?(Set)
35
+ args[0].to_a
36
+ else
37
+ args.to_a
38
+ end
39
+ Predicate.new(predicate, args: args, arg_type: "List")
12
40
  end
13
41
  end
14
42
  end
data/lib/grumlin/pop.rb CHANGED
@@ -9,7 +9,7 @@ module Grumlin
9
9
  name = "@#{step}"
10
10
  return instance_variable_get(name) if instance_variable_defined?(name)
11
11
 
12
- instance_variable_set(name, TypedValue.new("Pop", step))
12
+ instance_variable_set(name, TypedValue.new(type: "Pop", value: step))
13
13
  end
14
14
  end
15
15
  end
@@ -44,7 +44,7 @@ module Grumlin
44
44
 
45
45
  request = @requests[request_id]
46
46
 
47
- check_errors!(response[:status])
47
+ check_errors!(response[:status], request[:request])
48
48
 
49
49
  case SUCCESS[response.dig(:status, :code)]
50
50
  when :success
@@ -77,9 +77,9 @@ module Grumlin
77
77
 
78
78
  private
79
79
 
80
- def check_errors!(status)
80
+ def check_errors!(status, query)
81
81
  if (error = ERRORS[status[:code]])
82
- raise(error, status)
82
+ raise error.new(status, query)
83
83
  end
84
84
 
85
85
  return unless SUCCESS[status[:code]].nil?
data/lib/grumlin/step.rb CHANGED
@@ -10,8 +10,18 @@ module Grumlin
10
10
  end
11
11
 
12
12
  def next
13
- @enum ||= toList.to_enum
14
- @enum.next
13
+ to_enum.next
14
+ end
15
+
16
+ def hasNext # rubocop:disable Naming/MethodName
17
+ to_enum.peek
18
+ true
19
+ rescue StopIteration
20
+ false
21
+ end
22
+
23
+ def to_enum
24
+ @to_enum ||= toList.to_enum
15
25
  end
16
26
 
17
27
  def toList
data/lib/grumlin/t.rb CHANGED
@@ -9,7 +9,7 @@ module Grumlin
9
9
  name = "@#{step}"
10
10
  return instance_variable_get(name) if instance_variable_defined?(name)
11
11
 
12
- instance_variable_set(name, TypedValue.new("T", step))
12
+ instance_variable_set(name, TypedValue.new(type: "T", value: step))
13
13
  end
14
14
  end
15
15
  end
@@ -1,19 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Grumlin
4
- # TODO: find a better name
5
4
  class TypedValue
6
- def initialize(type, value)
5
+ attr_reader :type, :value
6
+
7
+ def initialize(type: nil, value: nil)
7
8
  @type = type
8
9
  @value = value
9
10
  end
10
11
 
11
12
  def to_bytecode
12
- @to_bytecode ||= { "@type": "g:#{@type}", "@value": @value }
13
+ @to_bytecode ||= if type.nil?
14
+ value
15
+ else
16
+ {
17
+ "@type": "g:#{type}",
18
+ "@value": value
19
+ }
20
+ end
13
21
  end
14
22
 
15
23
  def inspect
16
- "<#{@type}.#{@value}>"
24
+ "<#{type}.#{value}>"
17
25
  end
18
26
  alias to_s inspect
19
27
  alias to_readable_bytecode inspect
data/lib/grumlin/u.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Grumlin
4
4
  module U
5
5
  # TODO: add other start steps
6
- SUPPORTED_START_STEPS = %w[V addV count has out unfold values].freeze
6
+ SUPPORTED_START_STEPS = %w[V addV count fold has out repeat unfold values].freeze
7
7
 
8
8
  class << self
9
9
  SUPPORTED_START_STEPS.each do |step|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Grumlin
4
- VERSION = "0.8.0"
4
+ VERSION = "0.11.0"
5
5
  end
data/lib/grumlin.rb CHANGED
@@ -57,11 +57,12 @@ module Grumlin
57
57
  class UnknownTypeError < ProtocolError; end
58
58
 
59
59
  class StatusError < Error
60
- attr_reader :status
60
+ attr_reader :status, :query
61
61
 
62
- def initialize(status)
62
+ def initialize(status, query)
63
63
  super(status[:message])
64
64
  @status = status
65
+ @query = query
65
66
  end
66
67
  end
67
68
 
@@ -103,16 +104,10 @@ module Grumlin
103
104
  @client_concurrency = 5
104
105
  @client_factory = ->(url, parent) { Grumlin::Client.new(url, parent: parent) }
105
106
  end
106
-
107
- def default_pool
108
- @default_pool ||= Async::Pool::Controller.new(Grumlin::Client::PoolResource, limit: pool_size)
109
- end
110
-
111
- def reset!
112
- @default_pool = nil
113
- end
114
107
  end
115
108
 
109
+ @pool_mutex = Mutex.new
110
+
116
111
  class << self
117
112
  def configure
118
113
  yield config
@@ -123,14 +118,26 @@ module Grumlin
123
118
  end
124
119
 
125
120
  def default_pool
126
- config.default_pool
121
+ if Thread.current.thread_variable_get(:grumlin_default_pool)
122
+ return Thread.current.thread_variable_get(:grumlin_default_pool)
123
+ end
124
+
125
+ @pool_mutex.synchronize do
126
+ Thread.current.thread_variable_set(:grumlin_default_pool,
127
+ Async::Pool::Controller.new(Grumlin::Client::PoolResource,
128
+ limit: config.pool_size))
129
+ end
127
130
  end
128
131
 
129
132
  def close
130
- default_pool.wait while default_pool.busy?
131
-
132
- default_pool.close
133
- config.reset!
133
+ return if Thread.current.thread_variable_get(:grumlin_default_pool).nil?
134
+
135
+ @pool_mutex.synchronize do
136
+ pool = Thread.current.thread_variable_get(:grumlin_default_pool)
137
+ pool.wait while pool.busy?
138
+ pool.close
139
+ Thread.current.thread_variable_set(:grumlin_default_pool, nil)
140
+ end
134
141
  end
135
142
  end
136
143
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grumlin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gleb Sinyavskiy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-07 00:00:00.000000000 Z
11
+ date: 2021-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-pool