sidekiq 3.4.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sidekiq might be problematic. Click here for more details.

Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/4.0-Upgrade.md +50 -0
  3. data/COMM-LICENSE +55 -45
  4. data/Changes.md +73 -1
  5. data/Ent-Changes.md +66 -0
  6. data/Gemfile +7 -1
  7. data/Pro-2.0-Upgrade.md +2 -2
  8. data/Pro-3.0-Upgrade.md +46 -0
  9. data/Pro-Changes.md +65 -2
  10. data/README.md +8 -9
  11. data/bin/sidekiq +5 -0
  12. data/bin/sidekiqctl +8 -2
  13. data/bin/sidekiqload +167 -0
  14. data/lib/sidekiq/api.rb +29 -31
  15. data/lib/sidekiq/cli.rb +41 -42
  16. data/lib/sidekiq/client.rb +5 -10
  17. data/lib/sidekiq/fetch.rb +35 -111
  18. data/lib/sidekiq/launcher.rb +102 -42
  19. data/lib/sidekiq/manager.rb +78 -180
  20. data/lib/sidekiq/middleware/server/logging.rb +10 -5
  21. data/lib/sidekiq/middleware/server/retry_jobs.rb +5 -5
  22. data/lib/sidekiq/processor.rb +126 -97
  23. data/lib/sidekiq/redis_connection.rb +23 -5
  24. data/lib/sidekiq/scheduled.rb +47 -26
  25. data/lib/sidekiq/testing.rb +96 -17
  26. data/lib/sidekiq/util.rb +20 -0
  27. data/lib/sidekiq/version.rb +1 -1
  28. data/lib/sidekiq/web.rb +17 -1
  29. data/lib/sidekiq/web_helpers.rb +26 -4
  30. data/lib/sidekiq/worker.rb +14 -0
  31. data/lib/sidekiq.rb +37 -14
  32. data/sidekiq.gemspec +11 -11
  33. data/test/helper.rb +45 -10
  34. data/test/test_actors.rb +137 -0
  35. data/test/test_api.rb +388 -388
  36. data/test/test_cli.rb +29 -59
  37. data/test/test_client.rb +60 -135
  38. data/test/test_extensions.rb +29 -23
  39. data/test/test_fetch.rb +2 -57
  40. data/test/test_launcher.rb +80 -0
  41. data/test/test_logging.rb +1 -1
  42. data/test/test_manager.rb +16 -131
  43. data/test/test_middleware.rb +3 -5
  44. data/test/test_processor.rb +110 -76
  45. data/test/test_rails.rb +21 -0
  46. data/test/test_redis_connection.rb +0 -1
  47. data/test/test_retry.rb +114 -162
  48. data/test/test_scheduled.rb +11 -17
  49. data/test/test_scheduling.rb +20 -42
  50. data/test/test_sidekiq.rb +46 -16
  51. data/test/test_testing.rb +80 -20
  52. data/test/test_testing_fake.rb +68 -8
  53. data/test/test_testing_inline.rb +3 -3
  54. data/test/test_util.rb +16 -0
  55. data/test/test_web.rb +17 -3
  56. data/test/test_web_helpers.rb +3 -2
  57. data/web/assets/images/favicon.ico +0 -0
  58. data/web/assets/javascripts/application.js +6 -1
  59. data/web/assets/javascripts/dashboard.js +2 -8
  60. data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +14 -14
  61. data/web/assets/stylesheets/application.css +33 -56
  62. data/web/locales/de.yml +1 -1
  63. data/web/locales/en.yml +1 -0
  64. data/web/locales/{no.yml → nb.yml} +10 -2
  65. data/web/locales/uk.yml +76 -0
  66. data/web/views/_footer.erb +2 -7
  67. data/web/views/_job_info.erb +1 -1
  68. data/web/views/_nav.erb +2 -2
  69. data/web/views/_poll_js.erb +5 -0
  70. data/web/views/{_poll.erb → _poll_link.erb} +0 -3
  71. data/web/views/busy.erb +2 -1
  72. data/web/views/dead.erb +1 -0
  73. data/web/views/layout.erb +2 -0
  74. data/web/views/morgue.erb +3 -0
  75. data/web/views/queue.erb +1 -0
  76. data/web/views/queues.erb +1 -0
  77. data/web/views/retries.erb +3 -0
  78. data/web/views/retry.erb +1 -0
  79. data/web/views/scheduled.erb +1 -0
  80. data/web/views/scheduled_job_info.erb +1 -0
  81. metadata +81 -47
  82. data/lib/sidekiq/actor.rb +0 -39
  83. data/test/test_worker_generator.rb +0 -17
data/test/test_testing.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require_relative 'helper'
2
- require 'sidekiq'
3
- require 'sidekiq/worker'
2
+
4
3
  require 'active_record'
5
4
  require 'action_mailer'
6
5
  require 'sidekiq/rails'
@@ -13,7 +12,7 @@ class TestTesting < Sidekiq::Test
13
12
  describe 'sidekiq testing' do
14
13
  describe 'require/load sidekiq/testing.rb' do
15
14
  before do
16
- require 'sidekiq/testing.rb'
15
+ require 'sidekiq/testing'
17
16
  end
18
17
 
19
18
  after do
@@ -22,37 +21,43 @@ class TestTesting < Sidekiq::Test
22
21
 
23
22
  it 'enables fake testing' do
24
23
  Sidekiq::Testing.fake!
25
- assert_equal true, Sidekiq::Testing.enabled?
26
- assert_equal true, Sidekiq::Testing.fake?
24
+ assert Sidekiq::Testing.enabled?
25
+ assert Sidekiq::Testing.fake?
26
+ refute Sidekiq::Testing.inline?
27
27
  end
28
28
 
29
29
  it 'enables fake testing in a block' do
30
30
  Sidekiq::Testing.disable!
31
- assert_equal true, Sidekiq::Testing.disabled?
31
+ assert Sidekiq::Testing.disabled?
32
+ refute Sidekiq::Testing.fake?
32
33
 
33
34
  Sidekiq::Testing.fake! do
34
- assert_equal true, Sidekiq::Testing.enabled?
35
- assert_equal true, Sidekiq::Testing.fake?
35
+ assert Sidekiq::Testing.enabled?
36
+ assert Sidekiq::Testing.fake?
37
+ refute Sidekiq::Testing.inline?
36
38
  end
37
39
 
38
- assert_equal false, Sidekiq::Testing.enabled?
39
- assert_equal false, Sidekiq::Testing.fake?
40
+ refute Sidekiq::Testing.enabled?
41
+ refute Sidekiq::Testing.fake?
40
42
  end
41
43
 
42
44
  it 'disables testing in a block' do
43
45
  Sidekiq::Testing.fake!
46
+ assert Sidekiq::Testing.fake?
44
47
 
45
48
  Sidekiq::Testing.disable! do
46
- assert_equal true, Sidekiq::Testing.disabled?
49
+ refute Sidekiq::Testing.fake?
50
+ assert Sidekiq::Testing.disabled?
47
51
  end
48
52
 
49
- assert_equal true, Sidekiq::Testing.enabled?
53
+ assert Sidekiq::Testing.fake?
54
+ assert Sidekiq::Testing.enabled?
50
55
  end
51
56
  end
52
57
 
53
58
  describe 'require/load sidekiq/testing/inline.rb' do
54
59
  before do
55
- require 'sidekiq/testing/inline.rb'
60
+ require 'sidekiq/testing/inline'
56
61
  end
57
62
 
58
63
  after do
@@ -61,22 +66,77 @@ class TestTesting < Sidekiq::Test
61
66
 
62
67
  it 'enables inline testing' do
63
68
  Sidekiq::Testing.inline!
64
- assert_equal true, Sidekiq::Testing.enabled?
65
- assert_equal true, Sidekiq::Testing.inline?
69
+ assert Sidekiq::Testing.enabled?
70
+ assert Sidekiq::Testing.inline?
71
+ refute Sidekiq::Testing.fake?
66
72
  end
67
73
 
68
74
  it 'enables inline testing in a block' do
69
75
  Sidekiq::Testing.disable!
70
- assert_equal true, Sidekiq::Testing.disabled?
76
+ assert Sidekiq::Testing.disabled?
77
+ refute Sidekiq::Testing.fake?
71
78
 
72
79
  Sidekiq::Testing.inline! do
73
- assert_equal true, Sidekiq::Testing.enabled?
74
- assert_equal true, Sidekiq::Testing.inline?
80
+ assert Sidekiq::Testing.enabled?
81
+ assert Sidekiq::Testing.inline?
75
82
  end
76
83
 
77
- assert_equal false, Sidekiq::Testing.enabled?
78
- assert_equal false, Sidekiq::Testing.inline?
84
+ refute Sidekiq::Testing.enabled?
85
+ refute Sidekiq::Testing.inline?
86
+ refute Sidekiq::Testing.fake?
79
87
  end
80
88
  end
81
89
  end
90
+
91
+ describe 'with middleware' do
92
+ before do
93
+ require 'sidekiq/testing'
94
+ end
95
+
96
+ after do
97
+ Sidekiq::Testing.disable!
98
+ end
99
+
100
+ class AttributeWorker
101
+ include Sidekiq::Worker
102
+ class_attribute :count
103
+ self.count = 0
104
+ attr_accessor :foo
105
+
106
+ def perform
107
+ self.class.count += 1 if foo == :bar
108
+ end
109
+ end
110
+
111
+ class AttributeMiddleware
112
+ def call(worker, msg, queue)
113
+ worker.foo = :bar if worker.respond_to?(:foo=)
114
+ yield
115
+ end
116
+ end
117
+
118
+ it 'wraps the inlined worker with middleware' do
119
+ Sidekiq::Testing.server_middleware do |chain|
120
+ chain.add AttributeMiddleware
121
+ end
122
+
123
+ begin
124
+ Sidekiq::Testing.fake! do
125
+ AttributeWorker.perform_async
126
+ assert_equal 0, AttributeWorker.count
127
+ end
128
+
129
+ AttributeWorker.perform_one
130
+ assert_equal 1, AttributeWorker.count
131
+
132
+ Sidekiq::Testing.inline! do
133
+ AttributeWorker.perform_async
134
+ assert_equal 2, AttributeWorker.count
135
+ end
136
+ ensure
137
+ Sidekiq::Testing.server_middleware.clear
138
+ end
139
+ end
140
+ end
141
+
82
142
  end
@@ -1,6 +1,5 @@
1
1
  require_relative 'helper'
2
- require 'sidekiq'
3
- require 'sidekiq/worker'
2
+
4
3
  require 'active_record'
5
4
  require 'action_mailer'
6
5
  require 'sidekiq/rails'
@@ -47,7 +46,7 @@ class TestTesting < Sidekiq::Test
47
46
  end
48
47
 
49
48
  before do
50
- require 'sidekiq/testing.rb'
49
+ require 'sidekiq/testing'
51
50
  Sidekiq::Testing.fake!
52
51
  EnqueuedWorker.jobs.clear
53
52
  DirectWorker.jobs.clear
@@ -55,6 +54,7 @@ class TestTesting < Sidekiq::Test
55
54
 
56
55
  after do
57
56
  Sidekiq::Testing.disable!
57
+ Sidekiq::Queues.clear_all
58
58
  end
59
59
 
60
60
  it 'stubs the async call' do
@@ -94,7 +94,7 @@ class TestTesting < Sidekiq::Test
94
94
  it 'stubs the enqueue_to call' do
95
95
  assert_equal 0, EnqueuedWorker.jobs.size
96
96
  assert Sidekiq::Client.enqueue_to('someq', EnqueuedWorker, 1, 2)
97
- assert_equal 1, EnqueuedWorker.jobs.size
97
+ assert_equal 1, Sidekiq::Queues['someq'].size
98
98
  end
99
99
 
100
100
  it 'executes all stored jobs' do
@@ -106,7 +106,6 @@ class TestTesting < Sidekiq::Test
106
106
  StoredWorker.drain
107
107
  end
108
108
  assert_equal 0, StoredWorker.jobs.size
109
-
110
109
  end
111
110
 
112
111
  class SpecificJidWorker
@@ -263,9 +262,70 @@ class TestTesting < Sidekiq::Test
263
262
  end
264
263
 
265
264
  it 'can execute a job' do
266
- worker = Minitest::Mock.new
267
- worker.expect(:perform, nil, [1, 2, 3])
268
- DirectWorker.execute_job(worker, [1, 2, 3])
265
+ DirectWorker.execute_job(DirectWorker.new, [2, 3])
266
+ end
267
+ end
268
+
269
+ describe 'queue testing' do
270
+ before do
271
+ require 'sidekiq/testing'
272
+ Sidekiq::Testing.fake!
273
+ end
274
+
275
+ after do
276
+ Sidekiq::Testing.disable!
277
+ Sidekiq::Queues.clear_all
278
+ end
279
+
280
+ class QueueWorker
281
+ include Sidekiq::Worker
282
+ def perform(a, b)
283
+ a + b
284
+ end
285
+ end
286
+
287
+ class AltQueueWorker
288
+ include Sidekiq::Worker
289
+ sidekiq_options queue: :alt
290
+ def perform(a, b)
291
+ a + b
292
+ end
293
+ end
294
+
295
+ it 'finds enqueued jobs' do
296
+ assert_equal 0, Sidekiq::Queues["default"].size
297
+
298
+ QueueWorker.perform_async(1, 2)
299
+ QueueWorker.perform_async(1, 2)
300
+ AltQueueWorker.perform_async(1, 2)
301
+
302
+ assert_equal 2, Sidekiq::Queues["default"].size
303
+ assert_equal [1, 2], Sidekiq::Queues["default"].first["args"]
304
+
305
+ assert_equal 1, Sidekiq::Queues["alt"].size
306
+ end
307
+
308
+ it 'clears out all queues' do
309
+ assert_equal 0, Sidekiq::Queues["default"].size
310
+
311
+ QueueWorker.perform_async(1, 2)
312
+ QueueWorker.perform_async(1, 2)
313
+ AltQueueWorker.perform_async(1, 2)
314
+
315
+ Sidekiq::Queues.clear_all
316
+
317
+ assert_equal 0, Sidekiq::Queues["default"].size
318
+ assert_equal 0, Sidekiq::Queues["alt"].size
319
+ end
320
+
321
+ it 'finds jobs enqueued by client' do
322
+ Sidekiq::Client.push(
323
+ 'class' => 'NonExistentWorker',
324
+ 'queue' => 'missing',
325
+ 'args' => [1]
326
+ )
327
+
328
+ assert_equal 1, Sidekiq::Queues["missing"].size
269
329
  end
270
330
  end
271
331
  end
@@ -1,6 +1,5 @@
1
1
  require_relative 'helper'
2
- require 'sidekiq'
3
- require 'sidekiq/worker'
2
+
4
3
  require 'active_record'
5
4
  require 'action_mailer'
6
5
  require 'sidekiq/rails'
@@ -42,7 +41,7 @@ class TestInline < Sidekiq::Test
42
41
  end
43
42
 
44
43
  before do
45
- require 'sidekiq/testing/inline.rb'
44
+ require 'sidekiq/testing/inline'
46
45
  Sidekiq::Testing.inline!
47
46
  end
48
47
 
@@ -89,5 +88,6 @@ class TestInline < Sidekiq::Test
89
88
  it 'should relay parameters through json' do
90
89
  assert Sidekiq::Client.enqueue(InlineWorkerWithTimeParam, Time.now)
91
90
  end
91
+
92
92
  end
93
93
  end
data/test/test_util.rb ADDED
@@ -0,0 +1,16 @@
1
+ require_relative 'helper'
2
+
3
+ class TestUtil < Sidekiq::Test
4
+
5
+ class Helpers
6
+ include Sidekiq::Util
7
+ end
8
+
9
+ def test_hertz_donut
10
+ obj = Helpers.new
11
+ output = capture_logging(Logger::DEBUG) do
12
+ assert_equal false, obj.want_a_hertz_donut?
13
+ end
14
+ assert_includes output, "hz: 10"
15
+ end
16
+ end
data/test/test_web.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # encoding: utf-8
2
2
  require_relative 'helper'
3
- require 'sidekiq'
4
3
  require 'sidekiq/web'
5
4
  require 'rack/test'
5
+ require 'tilt/erubis'
6
6
 
7
7
  class TestWeb < Sidekiq::Test
8
8
 
@@ -18,7 +18,6 @@ class TestWeb < Sidekiq::Test
18
18
  end
19
19
 
20
20
  before do
21
- Sidekiq.redis = REDIS
22
21
  Sidekiq.redis {|c| c.flushdb }
23
22
  end
24
23
 
@@ -40,6 +39,15 @@ class TestWeb < Sidekiq::Test
40
39
  rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'en-us'}
41
40
  get '/', {}, rackenv
42
41
  assert_match(/Dashboard/, last_response.body)
42
+ rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'zh-cn'}
43
+ get '/', {}, rackenv
44
+ assert_match(/信息板/, last_response.body)
45
+ rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'zh-tw'}
46
+ get '/', {}, rackenv
47
+ assert_match(/資訊主頁/, last_response.body)
48
+ rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'nb'}
49
+ get '/', {}, rackenv
50
+ assert_match(/Oversikt/, last_response.body)
43
51
  end
44
52
 
45
53
  describe 'busy' do
@@ -292,7 +300,13 @@ class TestWeb < Sidekiq::Test
292
300
 
293
301
  get '/queues/default'
294
302
  assert_equal 200, last_response.status
295
- assert_match /#{msg['args'][2]}/, last_response.body
303
+ assert_match(/#{msg['args'][2]}/, last_response.body)
304
+ end
305
+
306
+ it 'calls updatePage() once when polling' do
307
+ get '/busy?poll=true'
308
+ assert_equal 200, last_response.status
309
+ assert_equal 1, last_response.body.scan('updatePage(').count
296
310
  end
297
311
 
298
312
  it 'escape job args and error messages' do
@@ -1,6 +1,4 @@
1
1
  require_relative 'helper'
2
- require 'sidekiq'
3
- require 'sidekiq/web_helpers'
4
2
 
5
3
  class TestWebHelpers < Sidekiq::Test
6
4
 
@@ -43,6 +41,9 @@ class TestWebHelpers < Sidekiq::Test
43
41
  obj = Helpers.new('HTTP_ACCEPT_LANGUAGE' => 'zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2')
44
42
  assert_equal 'zh-cn', obj.locale
45
43
 
44
+ obj = Helpers.new('HTTP_ACCEPT_LANGUAGE' => 'nb-NO,nb;q=0.2')
45
+ assert_equal 'nb', obj.locale
46
+
46
47
  obj = Helpers.new('HTTP_ACCEPT_LANGUAGE' => 'en-us; *')
47
48
  assert_equal 'en', obj.locale
48
49
 
Binary file
@@ -58,9 +58,14 @@ function updatePage(url) {
58
58
  url: url,
59
59
  dataType: 'html'
60
60
  }).done(function (data) {
61
- var $page = $(data).filter('#page')
61
+ $data = $(data)
62
+
63
+ var $page = $data.filter('#page')
62
64
  $('#page').replaceWith($page)
63
65
 
66
+ var $header_status = $data.find('.status')
67
+ $('.status').replaceWith($header_status)
68
+
64
69
  $("time").timeago()
65
70
  })
66
71
  }, parseInt(localStorage.timeInterval) || 2000);
@@ -227,14 +227,8 @@ var updateRedisStats = function(data) {
227
227
  }
228
228
 
229
229
  var pulseBeacon = function(){
230
- $beacon = $('.beacon')
231
- $beacon.find('.dot').addClass('pulse').delay(1000).queue(function(){
232
- $(this).removeClass('pulse');
233
- $(this).dequeue();
234
- });
235
- $beacon.find('.ring').addClass('pulse').delay(1000).queue(function(){
236
- $(this).removeClass('pulse');
237
- $(this).dequeue();
230
+ $('.beacon').addClass('pulse').delay(1000).queue(function(){
231
+ $(this).removeClass('pulse').dequeue();
238
232
  });
239
233
  }
240
234
 
@@ -1,16 +1,16 @@
1
- // Brazilian Portuguese
1
+ // Brasilian Portuguese
2
2
  jQuery.timeago.settings.strings = {
3
3
  suffixAgo: "atrás",
4
- suffixFromNow: "nesse momento",
5
- seconds: "alguns segundos",
6
- minute: " um minuto",
7
- minutes: "%d minutos",
8
- hour: " uma hora",
9
- hours: " %d horas",
10
- day: "um dia",
11
- days: "%d dias",
12
- month: " um mês",
13
- months: "%d meses",
14
- year: " um ano",
15
- years: "%d anos"
16
- };
4
+ suffixFromNow: "a partir de agora",
5
+ seconds: "menos de um minuto",
6
+ minute: "cerca de um minuto",
7
+ minutes: "%d minutos",
8
+ hour: "cerca de uma hora",
9
+ hours: "cerca de %d horas",
10
+ day: "um dia",
11
+ days: "%d dias",
12
+ month: "cerca de um mês",
13
+ months: "%d meses",
14
+ year: "cerca de um ano",
15
+ years: "%d anos"
16
+ };
@@ -181,6 +181,10 @@ form .btn {
181
181
  margin-right: 5px;
182
182
  }
183
183
 
184
+ form .btn-group .btn {
185
+ margin-right: 1px;
186
+ }
187
+
184
188
  td form {
185
189
  margin-bottom: 0;
186
190
  }
@@ -471,16 +475,22 @@ div.interval-slider input {
471
475
 
472
476
  .beacon {
473
477
  position: relative;
478
+ width: 20px;
474
479
  height: 20px;
475
480
  display: inline-block;
476
481
  }
477
482
 
478
- .beacon .dot {
483
+ .beacon .dot,
484
+ .beacon .ring {
479
485
  position: absolute;
480
- top: 5px;
481
- left: 10px;
486
+ top: 50%;
487
+ left: 50%;
488
+ }
489
+
490
+ .beacon .dot {
482
491
  width: 10px;
483
492
  height: 10px;
493
+ margin: -5px 0 0 -5px;
484
494
  background-color: #80002d;
485
495
  border-radius: 10px;
486
496
  box-shadow: 0 0 9px #666;
@@ -490,140 +500,103 @@ div.interval-slider input {
490
500
  z-index: 10;
491
501
  }
492
502
 
493
- .beacon .dot.pulse {
503
+ .beacon.pulse .dot {
494
504
  -webkit-animation: beacon-dot-pulse 1s ease-out;
495
505
  -moz-animation: beacon-dot-pulse 1s ease-out;
496
506
  animation: beacon-dot-pulse 1s ease-out;
497
- -webkit-animation-iteration-count: 1;
498
- -moz-animation-iteration-count: 1;
499
- animation-iteration-count: 1;
500
507
  }
501
508
 
502
509
  @-webkit-keyframes beacon-dot-pulse {
503
510
  from {
504
511
  background-color: #80002d;
505
512
  -webkit-box-shadow: 0 0 9px #666;
506
- -moz-box-shadow: 0 0 9px #666;
507
- box-shadow: 0 0 9px #666;
508
513
  }
509
514
  50% {
510
515
  background-color: #c90047;
511
516
  -webkit-box-shadow: 0 0 18px #666;
512
- -moz-box-shadow: 0 0 18px #666;
513
- box-shadow: 0 0 18px #666;
514
517
  }
515
518
  to {
516
519
  background-color: #80002d;
517
520
  -webkit-box-shadow: 0 0 9px #666;
518
- -moz-box-shadow: 0 0 9px #666;
519
- box-shadow: 0 0 9px #666;
520
521
  }
521
522
  }
522
523
 
523
524
  @-moz-keyframes beacon-dot-pulse {
524
525
  from {
525
526
  background-color: #80002d;
526
- -webkit-box-shadow: 0 0 9px #666;
527
527
  -moz-box-shadow: 0 0 9px #666;
528
- box-shadow: 0 0 9px #666;
529
528
  }
530
529
  50% {
531
530
  background-color: #c90047;
532
- -webkit-box-shadow: 0 0 18px #666;
533
531
  -moz-box-shadow: 0 0 18px #666;
534
- box-shadow: 0 0 18px #666;
535
532
  }
536
533
  to {
537
534
  background-color: #80002d;
538
- -webkit-box-shadow: 0 0 9px #666;
539
535
  -moz-box-shadow: 0 0 9px #666;
540
- box-shadow: 0 0 9px #666;
541
536
  }
542
537
  }
543
538
 
544
539
  @keyframes beacon-dot-pulse {
545
540
  from {
546
541
  background-color: #80002d;
547
- -webkit-box-shadow: 0 0 9px #666;
548
- -moz-box-shadow: 0 0 9px #666;
549
542
  box-shadow: 0 0 9px #666;
550
543
  }
551
544
  50% {
552
545
  background-color: #c90047;
553
- -webkit-box-shadow: 0 0 18px #666;
554
- -moz-box-shadow: 0 0 18px #666;
555
546
  box-shadow: 0 0 18px #666;
556
547
  }
557
548
  to {
558
549
  background-color: #80002d;
559
- -webkit-box-shadow: 0 0 9px #666;
560
- -moz-box-shadow: 0 0 9px #666;
561
550
  box-shadow: 0 0 9px #666;
562
551
  }
563
552
  }
564
553
 
565
554
  .beacon .ring {
566
- position: absolute;
567
- top: 7px;
568
- left: 12px;
569
- width: 0;
570
- height: 0;
571
- border-radius: 3px;
555
+ width: 28px;
556
+ height: 28px;
557
+ margin: -14px 0 0 -14px;
558
+ border-radius: 28px;
572
559
  border: 3px solid #80002d;
573
560
  z-index: 5;
561
+ opacity: 0;
574
562
  }
575
563
 
576
- .beacon .ring.pulse {
564
+ .beacon.pulse .ring {
577
565
  -webkit-animation: beacon-ring-pulse 1s;
578
566
  -moz-animation: beacon-ring-pulse 1s;
579
567
  animation: beacon-ring-pulse 1s;
580
- -webkit-animation-iteration-count: 1;
581
- -moz-animation-iteration-count: 1;
582
- animation-iteration-count: 1;
583
568
  }
584
569
 
585
570
  @-webkit-keyframes beacon-ring-pulse {
586
571
  0% {
587
572
  opacity: 1;
588
- -webkit-transform: scale(0);
573
+ -webkit-transform: scale(0.3);
589
574
  }
590
575
  100% {
591
576
  opacity: 0;
592
- border-radius: 15px;
593
- padding: 8px;
594
- top: 0;
595
- left: 4px;
596
- -webkit-transform: scale(1.5);
577
+ -webkit-transform: scale(1);
597
578
  }
598
579
  }
599
580
 
600
581
  @-moz-keyframes beacon-ring-pulse {
601
582
  0% {
602
583
  opacity: 1;
603
- -moz-transform: scale(0);
584
+ -moz-transform: scale(0.3);
604
585
  }
605
586
  100% {
606
587
  opacity: 0;
607
- border-radius: 15px;
608
- padding: 8px;
609
- top: 2px;
610
- left: 7px;
611
- -moz-transform: scale(1.6);
588
+ -moz-transform: scale(1);
612
589
  }
613
590
  }
614
591
 
615
592
  @keyframes beacon-ring-pulse {
616
593
  0% {
617
594
  opacity: 1;
618
- transform: scale(0);
595
+ transform: scale(0.3);
619
596
  }
620
597
  100% {
621
598
  opacity: 0;
622
- border-radius: 15px;
623
- padding: 8px;
624
- top: 0;
625
- left: 5px;
626
- transform: scale(1.5);
599
+ transform: scale(1);
627
600
  }
628
601
  }
629
602
 
@@ -759,19 +732,23 @@ div.interval-slider input {
759
732
 
760
733
  @media (min-width: 992px) {
761
734
  .redis-url {
762
- max-width: 340px;
735
+ max-width: 390px;
763
736
  }
764
737
 
765
738
  .redis-namespace {
766
- max-width: 350px;
739
+ max-width: 300px;
767
740
  }
768
741
  }
769
742
  @media (min-width: 1200px) {
770
743
  .redis-url {
771
- max-width: 540px;
744
+ max-width: 480px;
772
745
  }
773
746
 
774
747
  .redis-namespace {
775
748
  max-width: 350px;
776
749
  }
777
750
  }
751
+
752
+ .redis-url {
753
+ text-overflow: ellipsis;
754
+ }
data/web/locales/de.yml CHANGED
@@ -47,7 +47,7 @@ de:
47
47
  GoBack: ← Zurück
48
48
  NoScheduledFound: Keine geplanten Jobs gefunden
49
49
  When: Wann
50
- ScheduledJobs: Jobs in Wartschlange
50
+ ScheduledJobs: Jobs in der Warteschlange
51
51
  idle: inaktiv
52
52
  active: aktiv
53
53
  Version: Version
data/web/locales/en.yml CHANGED
@@ -74,3 +74,4 @@ en: # <---- change this to your locale code
74
74
  QuietAll: Quiet All
75
75
  PollingInterval: Polling interval
76
76
  Plugins: Plugins
77
+ NotYetEnqueued: Not yet enqueued