pomelo-citrus-scheduler 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 602975c89705979ad0a6b2477c38134e4c0ed8f2
4
+ data.tar.gz: 481027405914536c19e7300e5d93b2824a75397b
5
+ SHA512:
6
+ metadata.gz: 9e6929058f53f2b85b78370423e02668b718e23bc13606f141165ac2c02f56072c8abc77fae589562c76f3f89618eb33a4d1be9d3a6241d0de7c2411c035f2e9
7
+ data.tar.gz: e1c5c5ab749fa8a56a5218fb147027f52619231c6288444e0ec4a4f84ca40853e9c8cc58072f38918bf5fdbcf072fa94e140e45bfe1a92912eadbb96c0d44270
@@ -0,0 +1,20 @@
1
+ ## Welcome to pomelo-citrus-scheduler
2
+
3
+ pomelo-citrus-scheduler is a simple clone of pomelo-scheduler written in Ruby using EventMachine.
4
+
5
+ ## Motivation
6
+
7
+ Since NodeJS is influenced by Ruby EventMachine and Python's Twisted model, Ruby should also be able to have its own game server framework like pomelo.
8
+
9
+ Ruby is a very expressive and eloquent programming language. I was an RoR programmer before and I really like Ruby, When developing this project, I have used many skills like meta-programming and they give me the real pleasures.
10
+
11
+ Recently, I would focus on my daily work, so I open source this project and hope to have more people participate in this project.
12
+
13
+ ## Todo
14
+
15
+ This gem is the very first gem I have done in my whole work, it needs to be improved but it already has the ablity to provide the basic infrastructure to other gems, other gems exist in my own repository.
16
+
17
+ ## Links
18
+
19
+ * [EventMachine](https://github.com/eventmachine/eventmachine)
20
+ * [pomelo-scheduler](https://github.com/NetEase/pomelo-scheduler)
File without changes
@@ -0,0 +1,27 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 15 July 2014
4
+
5
+ $:.push File.expand_path('../lib', __FILE__)
6
+
7
+ require 'citrus-scheduler/version'
8
+
9
+ Gem::Specification.new do |spec|
10
+ spec.name = 'pomelo-citrus-scheduler'
11
+ spec.version = CitrusScheduler::VERSION
12
+ spec.platform = Gem::Platform::RUBY
13
+ spec.authors = ['MinixLi']
14
+ spec.email = 'MinixLi1986@gmail.com'
15
+ spec.description = %q{pomelo-citrus-scheduler is a simple clone of pomelo-scheduler, it is a schedule tool and provide a schedule module which is highly efficient and can support large number job schedule}
16
+ spec.summary = %q{pomelo-scheduler clone written in Ruby using EventMachine}
17
+ spec.homepage = 'https://github.com/minixli/pomelo-citrus-scheduler'
18
+ spec.license = 'MIT'
19
+
20
+ spec.files = `git ls-files`.split($/)
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_dependency('algorithms', '~> 0')
26
+ spec.add_dependency('eventmachine', '~> 0')
27
+ end
@@ -0,0 +1,8 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 15 July 2014
4
+
5
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
6
+
7
+ require 'eventmachine'
8
+ require 'citrus-scheduler/schedule'
@@ -0,0 +1,19 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 15 July 2014
4
+
5
+ require 'citrus-scheduler/cron_trigger_decoder'
6
+
7
+ module CitrusScheduler
8
+ # CronTrigger
9
+ #
10
+ #
11
+ class CronTrigger
12
+ # Create a new cron trigger
13
+ #
14
+ # @param [String] args
15
+ # @param [Object] job
16
+ def initialize args='', job
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 15 July 2014
4
+
5
+ module CitrusScheduler
6
+ # CronTrigger
7
+ #
8
+ #
9
+ class CronTriggerDecoder
10
+ # Create a new cron trigger decoder
11
+ def initialize
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,66 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 15 July 2014
4
+
5
+ require 'citrus-scheduler/cron_trigger'
6
+ require 'citrus-scheduler/simple_trigger'
7
+
8
+ module CitrusScheduler
9
+ # Job
10
+ #
11
+ #
12
+ class Job
13
+ @job_id = 1
14
+ @job_count = 0
15
+
16
+ class << self
17
+ attr_accessor :job_id, :job_count
18
+ end
19
+
20
+ attr_reader :job_id, :run_time
21
+
22
+ # Create a new job
23
+ #
24
+ # @param [#call] job_cb
25
+ # @param [Hash] job_cb_args
26
+ # @param [Hash, String] trigger_args
27
+ def initialize job_cb, job_cb_args={}, trigger_args={}
28
+ @job_cb = job_cb
29
+ @job_cb_args = job_cb_args
30
+
31
+ if trigger_args.instance_of? Hash
32
+ @type = :simple_job
33
+ @trigger = SimpleTrigger.new trigger_args, self
34
+ elsif trigger_args.instance_of? String
35
+ @type = :cron_job
36
+ @trigger = CronTrigger.new trigger_args, self
37
+ else
38
+ end
39
+
40
+ @job_id = Job.job_id
41
+ Job.job_id += 1
42
+
43
+ @run_time = 0
44
+ end
45
+
46
+ # Run the job
47
+ def run
48
+ begin
49
+ Job.job_count += 1
50
+ @run_time += 1
51
+ @job_cb.call @job_cb_args
52
+ rescue => err
53
+ end
54
+ end
55
+
56
+ # Get the current execution time
57
+ def execute_time
58
+ @trigger.execute_time
59
+ end
60
+
61
+ # Get the next execution time
62
+ def next_execute_time
63
+ @trigger.next_execute_time
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,114 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 15 July 2014
4
+
5
+ require 'algorithms'
6
+ require 'citrus-scheduler/job'
7
+
8
+ module CitrusScheduler
9
+ @jobs_map = {}
10
+ @jobs_queue = Containers::PriorityQueue.new
11
+ @timer = nil
12
+ @accuracy = 0.01
13
+
14
+ # Schedule a new job
15
+ #
16
+ # @param [#call] job_cb
17
+ # @param [Hash] job_cb_args
18
+ # @param [Hash] trigger_args
19
+ def self.schedule_job job_cb, job_cb_args={}, trigger_args={}
20
+ job = Job.new job_cb, job_cb_args, trigger_args
21
+ job_id = job.job_id
22
+ execute_time = job.execute_time
23
+
24
+ @jobs_map[job_id] = job
25
+ element = {
26
+ :job_id => job_id,
27
+ :execute_time => execute_time
28
+ }
29
+
30
+ cur_job = @jobs_queue.next
31
+ unless cur_job && execute_time >= cur_job[:execute_time]
32
+ @jobs_queue.push element, -execute_time
33
+ set_timer job
34
+ return job_id
35
+ end
36
+
37
+ @jobs_queue.push element, -execute_time
38
+ return job_id
39
+ end
40
+
41
+ # Cancel a job
42
+ #
43
+ # @param [Integer] job_id
44
+ def self.cancel_job job_id
45
+ cur_job = @jobs_queue.next
46
+ if cur_job && job_id == cur_job[:job_id]
47
+ @jobs_queue.pop
48
+ @jobs_map.delete job_id
49
+ @timer.cancel
50
+ execute_job
51
+ end
52
+ @jobs_map.delete job_id
53
+ true
54
+ end
55
+
56
+ # Clear last timeout and schedule the next job, it will automatically
57
+ # run the job that need to run now
58
+ #
59
+ # @param [Object] job
60
+ def self.set_timer job
61
+ @timer.cancel if @timer
62
+ @timer = EM::Timer.new(job.execute_time - Time.now.to_f) {
63
+ execute_job
64
+ }
65
+ end
66
+
67
+ # Execute job
68
+ def self.execute_job
69
+ job = peek_next_job
70
+
71
+ while job && (job.execute_time - Time.now.to_f) < @accuracy
72
+ job.run
73
+ @jobs_queue.pop
74
+
75
+ next_time = job.next_execute_time
76
+
77
+ if next_time
78
+ element = {
79
+ :job_id => job.job_id,
80
+ :execute_time => next_time
81
+ }
82
+ @jobs_queue.push element, -next_time
83
+ else
84
+ @jobs_map.delete job.job_id
85
+ end
86
+ job = peek_next_job
87
+ end
88
+
89
+ return unless job
90
+ set_timer job
91
+ end
92
+
93
+ # Peek next job
94
+ def self.peek_next_job
95
+ return nil if @jobs_queue.size <= 0
96
+
97
+ job = nil
98
+ loop do
99
+ job = @jobs_map[@jobs_queue.next[:job_id]]
100
+ @jobs_queue.pop unless job
101
+ break if job || @jobs_queue.size <= 0
102
+ end
103
+ job
104
+ end
105
+
106
+ # Get next job
107
+ def self.get_next_job
108
+ job = nil
109
+ while !job && @jobs_queue.size > 0
110
+ job = @jobs_map[@jobs_queue.pop[:job_id]]
111
+ end
112
+ job
113
+ end
114
+ end
@@ -0,0 +1,38 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 15 July 2014
4
+
5
+ module CitrusScheduler
6
+ # SimpleTrigger
7
+ #
8
+ #
9
+ class SimpleTrigger
10
+ # Create a new simple trigger
11
+ #
12
+ # @param [Hash] args Options
13
+ #
14
+ # @option args [Integer] start_time
15
+ # @option args [Integer] interval
16
+ # @option args [Integer] count
17
+ # @option args [Object] job
18
+ def initialize args={}, job
19
+ @next_time = args[:start_time] || Time.now.to_f
20
+ @interval = args[:interval] || -1
21
+ @count = args[:count] || -1
22
+ @job = job
23
+ end
24
+
25
+ # Get the current execution time
26
+ def execute_time
27
+ @next_time
28
+ end
29
+
30
+ # Get the next execution time
31
+ def next_execute_time
32
+ if (@count > 0 && @count <= @job.run_time) || @interval <= 0
33
+ return nil
34
+ end
35
+ @next_time += @interval
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,7 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 16 July 2014
4
+
5
+ module CitrusScheduler
6
+ VERSION = '0.0.1'
7
+ end
@@ -0,0 +1,28 @@
1
+ # Author:: MinixLi (gmail: MinixLi1986)
2
+ # Homepage:: http://citrus.inspawn.com
3
+ # Date:: 16 July 2014
4
+
5
+ require File.expand_path('../../lib/citrus-scheduler', __FILE__)
6
+
7
+ def simple_job_cb args={}
8
+ puts "simple job #{args[:id]} with interval: #{args[:interval]} executed at #{Time.now}"
9
+ end
10
+
11
+ def test_simple_job_schedule count
12
+ count.times do |count|
13
+ start_time = Time.now.to_f + rand * 10
14
+ interval = rand * 60 + 0.1
15
+ args = [
16
+ method(:simple_job_cb),
17
+ { :id => count, :interval => interval },
18
+ { :start_time => start_time, :interval => interval }
19
+ ]
20
+ CitrusScheduler.schedule_job *args
21
+ end
22
+ end
23
+
24
+ def test
25
+ test_simple_job_schedule 5
26
+ end
27
+
28
+ EM.run { test }
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pomelo-citrus-scheduler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - MinixLi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: algorithms
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: eventmachine
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: pomelo-citrus-scheduler is a simple clone of pomelo-scheduler, it is
42
+ a schedule tool and provide a schedule module which is highly efficient and can
43
+ support large number job schedule
44
+ email: MinixLi1986@gmail.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - README.md
50
+ - Rakefile
51
+ - citrus-scheduler.gemspec
52
+ - lib/citrus-scheduler.rb
53
+ - lib/citrus-scheduler/cron_trigger.rb
54
+ - lib/citrus-scheduler/cron_trigger_decoder.rb
55
+ - lib/citrus-scheduler/job.rb
56
+ - lib/citrus-scheduler/schedule.rb
57
+ - lib/citrus-scheduler/simple_trigger.rb
58
+ - lib/citrus-scheduler/version.rb
59
+ - test/test_schedule.rb
60
+ homepage: https://github.com/minixli/pomelo-citrus-scheduler
61
+ licenses:
62
+ - MIT
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 2.2.2
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: pomelo-scheduler clone written in Ruby using EventMachine
84
+ test_files:
85
+ - test/test_schedule.rb