kronos-ruby 0.2.1.alpha.9 → 0.2.1.alpha.10

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: e8c9e7b6c282c258f653df363494cafc1055c846
4
- data.tar.gz: 185bd729886a57bc22bb0d80e9f7d06f892fb2f9
3
+ metadata.gz: 94065dd5befb97c9a910ef8beb81af2986b63f1b
4
+ data.tar.gz: bc29df98662ec85c9830b9db4e2e3cee12a5e8c3
5
5
  SHA512:
6
- metadata.gz: 3d6bacf3bedb5e0d10f69daf22efdfd267c8ad79d27dd74ef02f030b0f41f972b4ae31d073bb9e374855bdb342b6243d51e0a64644ad7e2ee1b649db6a615e29
7
- data.tar.gz: 147b6a29ee3aa307de7880003da6a34fbd807c909e830e62d1b7b1f01f1959307c72559bf690289d056ddf62f0ac5ddaabf9aba4d5635205d379e5b531447812
6
+ metadata.gz: 5f49278e16b63184f277d3c7636ae47c7d6c0fedb2a948a48c4509fd2addd881eb2a8082df0fa094209180b477aaf75e7d9218f3cc710fe0978d9a272b917422
7
+ data.tar.gz: aa21e234ea82b1c543c939afc1ca81a85f96e7fb80aef542b78414ef50185ffa23af99edfd710c7b17adac8f79fd2f1cbd013867030fc74d6f2d500ec4bf38a1
data/README.md CHANGED
@@ -12,7 +12,7 @@ This project allows you to use a scheduler with well defined concepts of runners
12
12
  Add this line to your application's Gemfile:
13
13
 
14
14
  ```ruby
15
- gem 'kronos-ruby'
15
+ gem 'kronos-ruby', require: ['kronos']
16
16
  ```
17
17
 
18
18
  And then execute:
@@ -47,6 +47,15 @@ To view Krono's web dashboard, simply mount it into your Rack stack:
47
47
  mount Kronos::Web::App, at: '/kronos-dashboard'
48
48
  ```
49
49
 
50
+ If you want to protect Kronos dashboard, try using `Rack::Auth::Basic`:
51
+ ```ruby
52
+ protected_kronos = Rack::Auth::Basic.new(Kronos::Web::App) do |username, password|
53
+ # Check if username/password tuple is valid
54
+ end
55
+
56
+ mount protected_kronos, at: '/kronos-dashboard'
57
+ ```
58
+
50
59
  ## Developing
51
60
  - Clone this repository
52
61
  - Run `bin/setup` to install dependencies
@@ -4,6 +4,7 @@ require 'concurrent'
4
4
  require 'chronic'
5
5
  require 'erb'
6
6
  require 'ostruct'
7
+ require 'forwardable'
7
8
 
8
9
  require 'kronos/config_agent'
9
10
  require 'kronos/dependencies'
@@ -24,6 +24,7 @@ module Kronos
24
24
  def initialize(tasks, dependencies)
25
25
  @tasks = tasks
26
26
  @dependencies = dependencies
27
+ @lock_manager = LockManager.new(dependencies.storage)
27
28
  end
28
29
 
29
30
  def start
@@ -66,9 +67,10 @@ module Kronos
66
67
 
67
68
  # rubocop:disable RescueException
68
69
  def run_task(task)
69
- raw_execute_task(task)
70
+ task_id = task.id
71
+ @lock_manager.lock_and_execute(task_id) { raw_execute_task(task) }
70
72
  rescue ::Exception => error
71
- register_task_failure(task.id, error)
73
+ register_task_failure(task_id, error)
72
74
  end
73
75
  # rubocop:enable
74
76
 
@@ -109,3 +111,5 @@ module Kronos
109
111
  end
110
112
  end
111
113
  end
114
+
115
+ require 'kronos/runner/synchronous/lock_manager'
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kronos
4
+ module Runner
5
+ class Synchronous
6
+ class LockManager
7
+ extend Forwardable
8
+
9
+ def initialize(storage)
10
+ @storage = storage
11
+ end
12
+
13
+ def lock_and_execute(task_id)
14
+ return if locked_task?(task_id)
15
+ lock_id = lock_task(task_id)
16
+ return unless check_lock(task_id, lock_id)
17
+ yield
18
+ ensure
19
+ release_lock(task_id)
20
+ end
21
+
22
+ def_delegator :@storage, :locked_task?, :locked_task?
23
+ def_delegator :@storage, :lock_task, :lock_task
24
+ def_delegator :@storage, :check_lock, :check_lock
25
+ def_delegator :@storage, :release_lock, :release_lock
26
+ end
27
+ end
28
+ end
29
+ end
@@ -9,6 +9,7 @@ module Kronos
9
9
  def initialize
10
10
  @scheduled_tasks = []
11
11
  @reports = []
12
+ @locks = {}
12
13
  end
13
14
 
14
15
  def schedule(scheduled_task)
@@ -48,6 +49,24 @@ module Kronos
48
49
  def remove_reports_for(id)
49
50
  @reports.reject! { |report| report.task_id == id }
50
51
  end
52
+
53
+ def locked_task?(task_id)
54
+ @locks.key?(task_id)
55
+ end
56
+
57
+ def lock_task(task_id)
58
+ SecureRandom.uuid.tap do |lock_id|
59
+ @locks[task_id] = lock_id
60
+ end
61
+ end
62
+
63
+ def check_lock(task_id, lock_id)
64
+ @locks[task_id] == lock_id
65
+ end
66
+
67
+ def release_lock(task_id)
68
+ @locks.delete(task_id)
69
+ end
51
70
  end
52
71
  end
53
72
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mongoid'
4
+
5
+ module Kronos
6
+ module Storage
7
+ module Mongo
8
+ module Model
9
+ class LockModel
10
+ include Mongoid::Document
11
+ store_in collection: :kronos_locks
12
+
13
+ field :task_id, type: Symbol
14
+ field :value, type: String
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -2,13 +2,16 @@
2
2
 
3
3
  require 'kronos/storage/mongo/model/scheduled_task_model'
4
4
  require 'kronos/storage/mongo/model/report_model'
5
+ require 'kronos/storage/mongo/model/lock_model'
5
6
 
6
7
  module Kronos
7
8
  module Storage
8
9
  # :reek:UtilityFunction:
10
+ # :reek:TooManyMethods:
9
11
  class MongoDb
10
12
  SHEDULED_TASK_MODEL = Mongo::Model::ScheduledTaskModel
11
13
  REPORT_MODEL = Mongo::Model::ReportModel
14
+ LOCK_MODEL = Mongo::Model::LockModel
12
15
 
13
16
  def scheduled_tasks
14
17
  # Returns all current Kronos::ScheduledTask, resolved or pending
@@ -53,13 +56,31 @@ module Kronos
53
56
  query.exists? && query.first.next_run > Time.now
54
57
  end
55
58
 
59
+ def locked_task?(task_id)
60
+ LOCK_MODEL.where(task_id: task_id).exists?
61
+ end
62
+
63
+ def lock_task(task_id)
64
+ SecureRandom.uuid.tap do |lock_id|
65
+ LOCK_MODEL.create(task_id: task_id, value: lock_id)
66
+ end
67
+ end
68
+
69
+ def check_lock(task_id, lock_id)
70
+ LOCK_MODEL.where(task_id: task_id, value: lock_id).exists?
71
+ end
72
+
73
+ def release_lock(task_id)
74
+ LOCK_MODEL.where(task_id: task_id).destroy_all
75
+ end
76
+
56
77
  private
57
78
 
58
79
  def mount_report(report_model)
59
80
  case report_model.status
60
- when 0
81
+ when Kronos::Report::STATUSES[:success]
61
82
  mount_success_report(report_model)
62
- when 1
83
+ when Kronos::Report::STATUSES[:failure]
63
84
  mount_failure_report(report_model)
64
85
  end
65
86
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kronos-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1.alpha.9
4
+ version: 0.2.1.alpha.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriel Teles
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-09-25 00:00:00.000000000 Z
11
+ date: 2017-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -255,9 +255,11 @@ files:
255
255
  - lib/kronos/runner.rb
256
256
  - lib/kronos/runner/asynchronous.rb
257
257
  - lib/kronos/runner/synchronous.rb
258
+ - lib/kronos/runner/synchronous/lock_manager.rb
258
259
  - lib/kronos/scheduled_task.rb
259
260
  - lib/kronos/storage.rb
260
261
  - lib/kronos/storage/in_memory.rb
262
+ - lib/kronos/storage/mongo/model/lock_model.rb
261
263
  - lib/kronos/storage/mongo/model/report_model.rb
262
264
  - lib/kronos/storage/mongo/model/scheduled_task_model.rb
263
265
  - lib/kronos/storage/mongo_db.rb
@@ -286,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
286
288
  version: 1.3.1
287
289
  requirements: []
288
290
  rubyforge_project:
289
- rubygems_version: 2.4.8
291
+ rubygems_version: 2.6.13
290
292
  signing_key:
291
293
  specification_version: 4
292
294
  summary: Persistent cron jobs manager