stellate 0.0.3 → 1.1.0

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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/stellate.rb +79 -32
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e0373037e16a2f147c83f1083499e75f740ec4e92e426ca4382d9855227b1eb
4
- data.tar.gz: a1e8ecf717260acb276e5ae32d7997f823830278b48c24f487ab552aed75a77d
3
+ metadata.gz: 809048748b55d20deecab44e78b8bcb941f4cfd641c841d8757aef749483c8fc
4
+ data.tar.gz: a6c0540e65c193d0782d5360ac1024fcf8a44a11d81c45072bafc8875058ea30
5
5
  SHA512:
6
- metadata.gz: 6060f2aa4eed8b6d52f0494496cb9a16bd5471cc88b0c04b1f6d230439071cee1ad228950aaaf819e70755624e74062f19d216b8d3c1a535493a3318808ede28
7
- data.tar.gz: 77328738460721879b96ca8fdcd1a45defe31501e6bbaac4e442f31723107d5daae16b46f99feeb8ca47488b9e578d9e72c8019139e4aac26f8514f5a9dc4e3b
6
+ metadata.gz: 12df26863fbdfe982e1ad5a764504307b7d681d605bc014f248e5aeac273a5b936e54698f99129b738f682182563681ee5331939ec29b55154f570029de94cec
7
+ data.tar.gz: d6239d0fcabdab1736ec238ea7a0de6faf567251c584e3198ccb4585a805aef3df22a756345fec9a1f2c6f36a70afd342e9994b4fca1117c05fa924837196851
data/lib/stellate.rb CHANGED
@@ -4,7 +4,7 @@ require 'uri'
4
4
  require 'net/http'
5
5
 
6
6
  module Stellate
7
- VERSION = '0.0.3'
7
+ VERSION = '1.1.0'
8
8
 
9
9
  # Extend your GraphQL::Schema with this module to enable easy Stellate
10
10
  # Metrics Logging.
@@ -18,10 +18,16 @@ module Stellate
18
18
  # arguments as `GraphQL::Schema.execute()`, and also the following:
19
19
  # - `headers` (`ActionDispatch::Http::Headers`): The HTTP headers from the
20
20
  # incoming request
21
+ # - `callback` (`Method`): If passed, this will be called with a lambda as
22
+ # argument. Calling the passed lambda will log the request to Stellate
23
+ # via HTTP. This is useful if you want to move this request into a non-
24
+ # blocking process (e.g. using Sidekiq) rather than the default behavior
25
+ # of performing a blocking HTTP request which can increase overall
26
+ # response times of your API.
21
27
  def execute_with_logging(query_str = nil, **kwargs)
22
28
  starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
23
29
 
24
- result = execute(query_str, **kwargs.except(:service_name, :token, :headers))
30
+ result = execute(query_str, **kwargs.except(:headers, :callback))
25
31
 
26
32
  ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
27
33
  elapsed = (ending - starting) * 1000
@@ -48,14 +54,14 @@ module Stellate
48
54
 
49
55
  response = result.to_json
50
56
  payload = {
51
- "operation": query_str,
52
- "variableHash": create_blake3_hash(kwargs[:variables].to_json),
53
- "method": kwargs[:method].is_a?(String) ? kwargs[:method] : 'POST',
54
- "elapsed": elapsed.round,
55
- "responseSize": response.length,
56
- "responseHash": create_blake3_hash(response),
57
- "statusCode": 200,
58
- "operationName": kwargs[:operation_name]
57
+ 'operation' => query_str,
58
+ 'variableHash' => create_blake3_hash(kwargs[:variables].to_json),
59
+ 'method' => kwargs[:method].is_a?(String) ? kwargs[:method] : 'POST',
60
+ 'elapsed' => elapsed.round,
61
+ 'responseSize' => response.length,
62
+ 'responseHash' => create_blake3_hash(response),
63
+ 'statusCode' => 200,
64
+ 'operationName' => kwargs[:operation_name]
59
65
  }
60
66
 
61
67
  errors = result['errors']
@@ -65,22 +71,31 @@ module Stellate
65
71
  forwarded_for = headers['X-Forwarded-For']
66
72
  ips = forwarded_for.is_a?(String) ? forwarded_for.split(',') : []
67
73
 
68
- payload[:id] = ips[0] || headers['True-Client-Ip'] || headers['X-Real-Ip']
69
- payload[:userAgent] = headers['User-Agent']
70
- payload[:referer] = headers['referer']
74
+ payload['ip'] = ips[0] || headers['True-Client-Ip'] || headers['X-Real-Ip']
75
+ payload['userAgent'] = headers['User-Agent']
76
+ payload['referer'] = headers['referer']
77
+ payload['graphqlClientName'] = headers['x-graphql-client-name']
78
+ payload['graphqlClientVersion'] = headers['x-graphql-client-version']
71
79
  end
72
80
 
73
- # TODO: make this an async request to avoid blocking the response
74
- begin
75
- res = Net::HTTP.post(
76
- URI("https://#{@stellate_service_name}.stellate.sh/log"),
77
- payload.to_json,
81
+ stellate_request = {
82
+ 'url' => "https://#{@stellate_service_name}.stellate.sh/log",
83
+ 'headers' => {
78
84
  'Content-Type' => 'application/json',
79
85
  'Stellate-Logging-Token' => @stellate_token
80
- )
81
- puts "Failed to log metrics to Stellate: #{res.body}" if res.code.to_i >= 300
82
- rescue StandardError => e
83
- puts "Failed to log metrics to Stellate: #{e}"
86
+ },
87
+ 'body' => payload.to_json
88
+ }
89
+
90
+ callback = kwargs[:callback]
91
+ # The former check handles methods, the latter handles lambdas
92
+ if callback.is_a?(Method) || callback.respond_to?(:call)
93
+ callback.call(stellate_request)
94
+ # This handles symbols that contain methods
95
+ elsif callback.is_a?(Symbol) && method(callback).is_a?(Method)
96
+ method(callback).call(stellate_request)
97
+ else
98
+ run_stellate_request(stellate_request)
84
99
  end
85
100
 
86
101
  result
@@ -98,7 +113,15 @@ module Stellate
98
113
  # Use this plugin in your GraphQL::Schema to automatically sync your GraphQL
99
114
  # schema with your Stellate service.
100
115
  class SchemaSyncing
101
- def self.use(schema)
116
+ # The first argument is the GraphQLSchema class that this plugin is used
117
+ # on. It accepts the following names arguments:
118
+ # - `callback` (`Method`): If passed, this will be called with a lambda as
119
+ # argument. Calling the passed lambda will sync the schema to Stellate
120
+ # via HTTP. This is useful if you want to move this request into a non-
121
+ # blocking process (e.g. using Sidekiq) rather than the default behavior
122
+ # of performing a blocking HTTP request which can increase overall
123
+ # response times of your API.
124
+ def self.use(schema, **kwargs)
102
125
  unless schema.stellate_service_name.is_a?(String)
103
126
  puts 'Missing service name in order to sync schema to Stellate'
104
127
  return
@@ -111,20 +134,44 @@ module Stellate
111
134
 
112
135
  introspection = JSON.parse(schema.to_json)['data']
113
136
 
114
- # TODO: make this an async request to avoid blocking the request
115
- begin
116
- res = Net::HTTP.post(
117
- URI("https://#{schema.stellate_service_name}.stellate.sh/schema"),
118
- { schema: introspection }.to_json,
137
+ stellate_request = {
138
+ 'url' => "https://#{schema.stellate_service_name}.stellate.sh/schema",
139
+ 'headers' => {
119
140
  'Content-Type' => 'application/json',
120
141
  'Stellate-Schema-Token' => schema.stellate_token
121
- )
122
- puts "Failed to sync schema to Stellate: #{res.body}" if res.code.to_i >= 300
123
- rescue StandardError => e
124
- puts "Failed to sync schema to Stellate: #{e}"
142
+ },
143
+ 'body' => { schema: introspection }.to_json
144
+ }
145
+
146
+ callback = kwargs[:callback]
147
+ # The former check handles methods, the latter handles lambdas
148
+ if callback.is_a?(Method) || callback.respond_to?(:call)
149
+ callback.call(stellate_request)
150
+ # This handles symbols that contain methods
151
+ elsif callback.is_a?(Symbol) && method(callback).is_a?(Method)
152
+ method(callback).call(stellate_request)
153
+ else
154
+ run_stellate_request(stellate_request)
125
155
  end
126
156
  end
127
157
  end
158
+
159
+ def self.run_stellate_request(stellate_request)
160
+ url = URI.parse(stellate_request['url'])
161
+
162
+ http = Net::HTTP.new(url.host, url.port)
163
+ http.use_ssl = true
164
+
165
+ req = Net::HTTP::Post.new(url)
166
+ stellate_request['headers'].each do |key, value|
167
+ req[key] = value
168
+ end
169
+ req.body = stellate_request['body']
170
+ res = http.request(req)
171
+ puts "HTTP request to Stellate failed: #{res.body}" if res.code.to_i >= 300
172
+ rescue StandardError => e
173
+ puts "HTTP request to Stellate failed: #{e}"
174
+ end
128
175
  end
129
176
 
130
177
  def create_blake3_hash(str)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stellate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stellate
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-14 00:00:00.000000000 Z
11
+ date: 2024-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-http