skylight 0.2.4 → 0.2.5

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
  SHA1:
3
- metadata.gz: a3bbad2e6ff11878c301f0f6c35a19a700eb873e
4
- data.tar.gz: 6c5088d5d960e65149f89ced6ee48a5c7ff3c4dc
3
+ metadata.gz: 5ba19fdc679a43bb87c5cf95b843b05ce58878cb
4
+ data.tar.gz: 7cdf7d06b0eba50a07cbea357929bcd8b8231f73
5
5
  SHA512:
6
- metadata.gz: fd2dd401324a03a77b3ddc63f38d93cb4cfa7740f6603932e8c0b65f119c71d963637ffeb6f299d7eb427515232e230400014d5dec7b198340cf5f05835f4a01
7
- data.tar.gz: 746417c9a7a2600875374f2a783add8e2d08f6e5344b7f70f4fc6ba6292a3807535e5d4c0f80b27c1239c2e5e1b099ff250fef544ed7aaeb52a678465359313c
6
+ metadata.gz: c59d80d86beb6ff52709bb48a3182373ae2557f901419e4603dcaac64072f6144b3c6735fc2aef5fae3fd487647f230dd6c582f67b54052961e080aba307f120
7
+ data.tar.gz: 260f99fcf7b8a7b7074538e2083df7b334bbd4e1afd4b1e6874dbbaafc2616567127507e00c6bd7724c8a55c32b9cf479759d6eac0961fda6a8bbe10b02d5914
@@ -1,4 +1,4 @@
1
1
  module Skylight
2
- VERSION = '0.2.4'
2
+ VERSION = '0.2.5'
3
3
  end
4
4
 
@@ -327,7 +327,7 @@ module Skylight
327
327
 
328
328
  def get_memory_usage
329
329
  `ps -o rss= -p #{Process.pid}`.to_i / 1024
330
- rescue Errno::ENOENT
330
+ rescue Errno::ENOENT, Errno::EINTR
331
331
  0
332
332
  end
333
333
  end
@@ -2,4 +2,5 @@ require "sql_lexer/version"
2
2
  require "sql_lexer/lexer"
3
3
 
4
4
  module SqlLexer
5
+ # Your code goes here...
5
6
  end
@@ -29,8 +29,6 @@ module SqlLexer
29
29
  StartString = %Q<'>
30
30
  StartDigit = %q<[\p{Digit}\.]>
31
31
 
32
- StartSelect = %Q<SELECT(?=(?:[#{WS}]|#{OpPart}))>
33
-
34
32
  # Binds that are also IDs do not need to be included here, since AfterOp (which uses StartBind)
35
33
  # also checks for StartAnyId
36
34
  StartBind = %Q<#{StartString}|#{StartDigit}|#{SpecialOps}>
@@ -87,9 +85,7 @@ module SqlLexer
87
85
  TkArray = %r<#{ArrayOp}>iu
88
86
  TkArrayIndex = %r<#{ArrayIndexOp}>iu
89
87
  TkSpecialOp = %r<#{SpecialOps}>iu
90
- TkStartSelect = %r<#{StartSelect}>iu
91
- TkStartSubquery = %r<\(#{OptWS}#{StartSelect}>iu
92
- TkCloseParen = %r<#{OptWS}\)>u
88
+ TkStartSelect = %r<SELECT(?=(?:[#{WS}]|#{OpPart}))>iu
93
89
 
94
90
  STATE_HANDLERS = {
95
91
  begin: :process_begin,
@@ -101,7 +97,6 @@ module SqlLexer
101
97
  table_name: :process_table_name,
102
98
  end: :process_end,
103
99
  special: :process_special,
104
- subquery: :process_subquery,
105
100
  in: :process_in,
106
101
  array: :process_array
107
102
  }
@@ -356,12 +351,8 @@ module SqlLexer
356
351
  def process_special
357
352
  if @scanner.skip(TkIn)
358
353
  @scanner.skip(TkOptWS)
359
- if @scanner.skip(TkStartSubquery)
360
- @state = :subquery
361
- else
362
- @scanner.skip(/\(/u)
363
- @state = :in
364
- end
354
+ @scanner.skip(/\(/u)
355
+ @state = :in
365
356
  elsif @scanner.skip(TkArray)
366
357
  @scanner.skip(/\[/u)
367
358
  @state = :array
@@ -371,48 +362,11 @@ module SqlLexer
371
362
  else
372
363
  @state = :end
373
364
  end
374
- elsif @scanner.skip(TkStartSubquery)
375
- @state = :subquery
376
365
  elsif @scanner.skip(TkArrayIndex)
377
366
  @state = :tokens
378
367
  end
379
368
  end
380
369
 
381
- def process_subquery
382
- nest = 1
383
- iterations = 0
384
-
385
- while nest > 0
386
- iterations += 1
387
-
388
- if iterations > 10_000
389
- raise "The SQL '#{@scanner.string}' could not be parsed because of too many iterations in subquery"
390
- end
391
-
392
- if @debug
393
- p @state
394
- p @scanner
395
- p nest
396
- p @scanner.peek(1)
397
- end
398
-
399
- if @scanner.skip(TkStartSubquery)
400
- nest += 1
401
- @state = :tokens
402
- elsif @scanner.skip(TkCloseParen)
403
- nest -= 1
404
- break if nest.zero?
405
- @state = :tokens
406
- elsif @state == :subquery
407
- @state = :tokens
408
- end
409
-
410
- __send__ STATE_HANDLERS[@state]
411
- end
412
-
413
- @state = :tokens
414
- end
415
-
416
370
  def process_in
417
371
  nest = 1
418
372
  iterations = 0
@@ -436,7 +390,7 @@ module SqlLexer
436
390
  if @scanner.skip(/\(/u)
437
391
  nest += 1
438
392
  process_tokens
439
- elsif @scanner.skip(TkCloseParen)
393
+ elsif @scanner.skip(/\)/u)
440
394
  nest -= 1
441
395
  break if nest.zero?
442
396
  process_tokens
@@ -1,3 +1,3 @@
1
1
  module SqlLexer
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,62 @@
1
+ We received a notification (Zendesk #280) from a customer that they were unable to SSH
2
+ into their box, and that their service provider discovered that Skylight
3
+ was triggering socket buffer limits.
4
+
5
+ The customer immediately disabled Skylight, which fixed the bug for him.
6
+
7
+ Customer Information:
8
+
9
+ * Using Skylight 0.2.3
10
+ * Ruby 2.0.0p353
11
+ * Also had New Relic installed (Bug #46)
12
+ * Recently upgraded to Rails 4
13
+ * Passenger Enterprise with a max-pool size of 12 and zero-downtime deploys
14
+ * He had a maxsockbuf of 32MB
15
+
16
+ The customer also reported 134 open sockets in the server process.
17
+
18
+ Separately, we discovered that New Relic was making our payloads
19
+ extremely large.
20
+
21
+ Our working hypothesis was that the large New Relic payloads were
22
+ triggering the max buffer condition, which was then cascading into more
23
+ failures.
24
+
25
+ Upon further investigation, we discovered a few things:
26
+
27
+ * If the client hits a kernel buffer limit (via EWOULDBLOCK that lasts
28
+ more than 5s), it closes down its socket
29
+ * The server expects to recover from this situation by getting the
30
+ client socket in its read list from IO.select. It would then try to
31
+ read from it, get an EOF, and close the socket.
32
+ * If the server does not get the client socket in its read list for some
33
+ (unknown) reason, this would result in an ever-growing list of sockets
34
+ on the server side.
35
+
36
+ We are not sure why the sockets would not appear in the read list, but
37
+ we hypothesize that when the OpenVZ limit is reached, the kernel no
38
+ longer includes the socket in the read list, causing the server to never
39
+ close the socket.
40
+
41
+ Mitigation strategies:
42
+
43
+ * The New Relic fix (#46) should reduce the likelihood of encountering
44
+ this in the first place
45
+ * We want to add a Hello heartbeat from the client. If the server
46
+ doesn't receive a message every 1m (or 2m, TBD), it will close the
47
+ socket even if it's not in the read list.
48
+
49
+ We are worried that if the server process ever gets stuck, this
50
+ condition can occur. We are also considering a server heartbeat back to
51
+ the clients, so they can take corrective action if the agent gets stuck.
52
+
53
+ Some mitigations for this situation:
54
+
55
+ * Kill the server process when a respawn is necessary. This will ensure
56
+ that a stuck agent process doesn't duplicate into N servers.
57
+ * Before connecting to the server socket, pre-check the server process
58
+ with kill -0.
59
+
60
+ For next time:
61
+ * Request skylight.log for easier debugging
62
+ * Form a best practices for customer bug reporting on doc site
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skylight
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tilde, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-21 00:00:00.000000000 Z
11
+ date: 2014-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -142,6 +142,7 @@ files:
142
142
  - lib/sql_lexer.rb
143
143
  - lib/sql_lexer/lexer.rb
144
144
  - lib/sql_lexer/version.rb
145
+ - too-many-sockets.md
145
146
  homepage: http://www.skylight.io
146
147
  licenses: []
147
148
  metadata: {}