grumlin 1.0.3.beta1 → 1.0.3
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +2 -2
- data/lib/grumlin/dummy_transaction.rb +3 -5
- data/lib/grumlin/repository/instance_methods.rb +3 -3
- data/lib/grumlin/shortcuts/storage.rb +6 -2
- data/lib/grumlin/steppable.rb +1 -1
- data/lib/grumlin/transaction.rb +3 -1
- data/lib/grumlin/version.rb +1 -1
- metadata +4 -5
- data/doc/middlewares.md +0 -97
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d316bc1f39fbcec938151fb11d7e43f1043c0951062856bfe489651d41732f59
|
4
|
+
data.tar.gz: 7c3e294d9f38d1045a7ff991f07a27142ec92bbeee4a2b805c59dadcfb609dcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57987319c44b8f6a344b8a33d29c0380865857fdcec6c7fc536de7cd7282cd6804b846d9410a4e90d9eb0f22d8ac98ab9c06cd21b065fa7dce3e8e6e3b70d054
|
7
|
+
data.tar.gz: b4349848f8647a56ac01ed542743d16196526612ef2755781a47e7c0da70119ead2a67ac5123d02a8f563aec0215ec1c6af46896739aa83050c35921935e014f
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -262,7 +262,7 @@ Middlewares can be used to perform certain actions before and after every query
|
|
262
262
|
measuring query execution time or performing some modification or validation to the query before it reaches the server or
|
263
263
|
modify the response before client gets it.
|
264
264
|
|
265
|
-
See [
|
265
|
+
See [docs/middlewares.md](docs/middlewares.md) for more info and examples.
|
266
266
|
|
267
267
|
#### Transactions
|
268
268
|
|
@@ -379,7 +379,7 @@ See [docs/neptune.md](./docs/neptune.md)
|
|
379
379
|
|
380
380
|
#### Sidekiq
|
381
381
|
|
382
|
-
See [docs/
|
382
|
+
See [docs/sidekiq.md](./docs/sidekiq.md)
|
383
383
|
|
384
384
|
## Development
|
385
385
|
|
@@ -6,7 +6,7 @@ module Grumlin::Repository::InstanceMethods # rubocop:disable Metrics/ModuleLeng
|
|
6
6
|
extend Forwardable
|
7
7
|
|
8
8
|
def_delegator "self.class", :shortcuts
|
9
|
-
def_delegator :
|
9
|
+
def_delegator :shortcuts, :__
|
10
10
|
|
11
11
|
UPSERT_RETRY_PARAMS = {
|
12
12
|
on: [Grumlin::AlreadyExistsError, Grumlin::ConcurrentModificationError],
|
@@ -17,8 +17,8 @@ module Grumlin::Repository::InstanceMethods # rubocop:disable Metrics/ModuleLeng
|
|
17
17
|
|
18
18
|
DEFAULT_ERROR_HANDLING_STRATEGY = Grumlin::Repository::ErrorHandlingStrategy.new(mode: :retry, **UPSERT_RETRY_PARAMS)
|
19
19
|
|
20
|
-
def
|
21
|
-
shortcuts.
|
20
|
+
def g
|
21
|
+
shortcuts.g(middlewares: self.class.middlewares)
|
22
22
|
end
|
23
23
|
|
24
24
|
def drop_vertex(id, start: g)
|
@@ -35,7 +35,7 @@ class Grumlin::Shortcuts::Storage
|
|
35
35
|
sc = step_class
|
36
36
|
|
37
37
|
shortcut_methods_module.define_method(name) do |*args, **params|
|
38
|
-
next sc.new(name, args: args, params: params, previous_step: self, pool:
|
38
|
+
next sc.new(name, args: args, params: params, previous_step: self, pool: pool)
|
39
39
|
end
|
40
40
|
extend_traversal_classes(shortcut) unless shortcut.lazy?
|
41
41
|
end
|
@@ -46,8 +46,12 @@ class Grumlin::Shortcuts::Storage
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
def g(middlewares: Grumlin.default_middlewares)
|
50
|
+
traversal_start_class.new(pool: Grumlin.default_pool, middlewares: middlewares)
|
51
|
+
end
|
52
|
+
|
49
53
|
def __
|
50
|
-
traversal_start_class.new
|
54
|
+
traversal_start_class.new
|
51
55
|
end
|
52
56
|
|
53
57
|
def traversal_start_class
|
data/lib/grumlin/steppable.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
class Grumlin::Steppable
|
4
4
|
extend Forwardable
|
5
5
|
|
6
|
-
attr_reader :session_id
|
6
|
+
attr_reader :session_id, :pool
|
7
7
|
|
8
8
|
START_STEPS = Grumlin.definitions.dig(:steps, :start).map(&:to_sym).freeze
|
9
9
|
REGULAR_STEPS = Grumlin.definitions.dig(:steps, :regular).map(&:to_sym).freeze
|
data/lib/grumlin/transaction.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Grumlin::Transaction
|
4
|
-
attr_reader :session_id
|
4
|
+
attr_reader :session_id, :pool
|
5
5
|
|
6
6
|
include Console
|
7
7
|
|
@@ -34,5 +34,7 @@ class Grumlin::Transaction
|
|
34
34
|
need_results: false,
|
35
35
|
session_id: @session_id,
|
36
36
|
pool: @pool)
|
37
|
+
ensure
|
38
|
+
@pool.close
|
37
39
|
end
|
38
40
|
end
|
data/lib/grumlin/version.rb
CHANGED
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: 1.0.3
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gleb Sinyavskiy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-pool
|
@@ -118,7 +118,6 @@ files:
|
|
118
118
|
- Rakefile
|
119
119
|
- bin/console
|
120
120
|
- bin/setup
|
121
|
-
- doc/middlewares.md
|
122
121
|
- docker-compose.yml
|
123
122
|
- docs/neptune.md
|
124
123
|
- docs/sidekiq.md
|
@@ -217,9 +216,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
217
216
|
version: 2.7.0
|
218
217
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
219
218
|
requirements:
|
220
|
-
- - "
|
219
|
+
- - ">="
|
221
220
|
- !ruby/object:Gem::Version
|
222
|
-
version:
|
221
|
+
version: '0'
|
223
222
|
requirements: []
|
224
223
|
rubygems_version: 3.2.33
|
225
224
|
signing_key:
|
data/doc/middlewares.md
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
# Middlewares
|
2
|
-
|
3
|
-
Every single query performed by `Grumlin` goes through a stack of middlewares just like every single request in Rails
|
4
|
-
or many other web frameworks. `Grumlin` ships with a set of middlewares, each one performs some part of the query
|
5
|
-
execution process:
|
6
|
-
|
7
|
-
- `Middlewares::SerializeToSteps` - converts a `Step` into `Steps`
|
8
|
-
- `Middlewares::ApplyShortcuts` - applies shortcuts to `Steps`
|
9
|
-
- `Middlewares::SerializeToBytecode` - converts `Steps` into bytecode
|
10
|
-
- `Middlewares::BuildQuery` - builds an actual message that will be send to server
|
11
|
-
- `Middlewares::CastResults` - casts server response into ruby objects
|
12
|
-
- `Middlewares::RunQuery` - actually sends the message to the server
|
13
|
-
|
14
|
-
Normally these middlewares must never be rearranged or removed from the stack. Middlewares added after
|
15
|
-
`Middlewares::RunQuery` will not be executed.
|
16
|
-
|
17
|
-
## Writing a middleware for Grumlin
|
18
|
-
|
19
|
-
This entire feature is built on top of [ibsciss-middleware](https://github.com/Ibsciss/ruby-middleware) but uses a
|
20
|
-
slightly modified `Builder` which caches the chain for better performance.
|
21
|
-
Please refer to ibsciss-middleware docs if you want to implement a middleware.
|
22
|
-
|
23
|
-
|
24
|
-
A minimal middleware that measures query execution time and puts it back to `env`:
|
25
|
-
|
26
|
-
```ruby
|
27
|
-
class MeasureExecutionTime < Grumlin::Middlewares::Middleware # Middleware provides only an initializer with one argument for `app`
|
28
|
-
def call(env)
|
29
|
-
started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
30
|
-
result = @app.call(env)
|
31
|
-
env[:execution_time] = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started
|
32
|
-
result
|
33
|
-
end
|
34
|
-
end
|
35
|
-
```
|
36
|
-
|
37
|
-
When placed right before `Grumlin::Middlewares::CastResults` your middleware will have access to every intermediate result
|
38
|
-
of the query execution process:
|
39
|
-
- `env[:traversal]` - contains the original traversal
|
40
|
-
- `env[:steps]` - contains the `Steps` representing the traversal
|
41
|
-
- `env[:steps_without_shortcuts]` - contains the `Steps` representing the traversal, but with all shortcuts applied
|
42
|
-
- `env[:bytecode]` - raw bytecode of the traversal
|
43
|
-
- `env[:query]` - raw message that will be sent to the server. `requestId` can be found here: `env[:query][:requestId]`
|
44
|
-
|
45
|
-
After the query is performed (after `@app.call(env)`), these keys become available:
|
46
|
-
- `env[:results]` - raw results received from the server
|
47
|
-
- `env[:parsed_results]` - server results mapped to ruby types, basically the query results as the client gets it
|
48
|
-
|
49
|
-
Other useful parts of `env`:
|
50
|
-
- `env[:session_id]` - id of the session when executed inside a transaction, otherwise `nil`
|
51
|
-
- `env[:pool]` - connection pool that will be used to interact with the server
|
52
|
-
- `env[:need_results]` - flag stating whether the client needs the query execution results(`toList`, `next`) or not(`iterate`)
|
53
|
-
|
54
|
-
## Adding your middleware to the stack
|
55
|
-
|
56
|
-
There are two ways of adding middlewares to your queries:
|
57
|
-
- `global` - add the middleware to every single query from every single repository
|
58
|
-
- `per repository` - add the middleware to queries performed by particular repositories
|
59
|
-
|
60
|
-
Grumlin has one global middleware stack and every repository defines it's which is by default is a
|
61
|
-
copy of the global stack. This means one can easily modify repository's stack without worrying about the global one.
|
62
|
-
|
63
|
-
When inherited a class extending `Grumlin::Repository` will copy it's middlewares to the subclass, they can also be
|
64
|
-
modified independently from the parent's middlewares.
|
65
|
-
|
66
|
-
### Adding a middleware globally
|
67
|
-
```ruby
|
68
|
-
Grumlin.configure do |cfg|
|
69
|
-
cfg.url = ENV.fetch("GREMLIN_URL", "ws://localhost:8182/gremlin")
|
70
|
-
cfg.provider = :tinkergraph
|
71
|
-
|
72
|
-
cfg.middlewares do |b|
|
73
|
-
b.insert_before Grumlin::Middlewares::CastResults, MeasureExecutionTime
|
74
|
-
end
|
75
|
-
end
|
76
|
-
```
|
77
|
-
|
78
|
-
### Adding a middleware to a repository
|
79
|
-
```ruby
|
80
|
-
class MyRepository
|
81
|
-
# MyRepository inherits a copy of global middlewares
|
82
|
-
extend Grumlin::Repository
|
83
|
-
|
84
|
-
# SomeOtherMiddleware will be added to MyRepository's middlewares only
|
85
|
-
middlewares do |b|
|
86
|
-
b.insert_before Grumlin::Middlewares::CastResults, MeasureExecutionTime
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
class AnotherRepository < MyRepository
|
91
|
-
# AnotherRepository inherits parent's middlewares
|
92
|
-
middlewares do |b|
|
93
|
-
# SomeOtherMiddleware will be added to AnotherRepository's middlewares only
|
94
|
-
b.insert_before Grumlin::Middlewares::CastResults, SomeOtherMiddleware
|
95
|
-
end
|
96
|
-
end
|
97
|
-
```
|