khronos 0.0.0 → 0.0.1.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +18 -7
- data/Rakefile +36 -0
- data/bin/khronos +2 -1
- data/config.ru +9 -1
- data/config/environment.yml +27 -5
- data/{lib/khronos/storage/adapter/mongo/.schedule_log.rb.un~ → db/test.db} +0 -0
- data/khronos.gemspec +10 -7
- data/lib/khronos.rb +4 -7
- data/lib/khronos/config.rb +0 -2
- data/lib/khronos/logger.rb +16 -0
- data/lib/khronos/scheduler.rb +17 -3
- data/lib/khronos/server.rb +4 -31
- data/lib/khronos/server/controller.rb +31 -0
- data/lib/khronos/server/runner.rb +50 -0
- data/lib/khronos/server/scheduler.rb +110 -0
- data/lib/khronos/storage.rb +34 -13
- data/lib/khronos/storage/adapter.rb +44 -0
- data/lib/khronos/storage/adapter/activerecord.rb +39 -0
- data/lib/khronos/storage/adapter/activerecord/migrations/schedule.rb +29 -0
- data/lib/khronos/storage/adapter/activerecord/migrations/schedule_log.rb +23 -0
- data/lib/khronos/storage/adapter/activerecord/schedule.rb +24 -0
- data/lib/khronos/storage/adapter/activerecord/schedule_log.rb +14 -0
- data/lib/khronos/storage/adapter/mongoid.rb +37 -0
- data/lib/khronos/storage/adapter/{mongo → mongoid}/schedule.rb +6 -4
- data/lib/khronos/storage/adapter/{mongo → mongoid}/schedule_log.rb +3 -4
- data/lib/khronos/tasks/db.rake +25 -0
- data/lib/khronos/version.rb +1 -1
- data/server.rb +29 -0
- data/spec/functional/adapters_spec.rb +61 -0
- data/spec/functional/controller_spec.rb +11 -0
- data/spec/functional/scheduler_spec.rb +30 -0
- data/spec/integration/runner_server_spec.rb +26 -0
- data/spec/integration/scheduler_server_spec.rb +70 -0
- data/spec/spec_helper.rb +17 -1
- data/spec/support/factories.rb +12 -0
- data/spec/support/mocks.rb +23 -0
- data/{lib/khronos/storage/adapter/postgres/.schedule.rb.un~ → spec/tmp/scheduler.db} +0 -0
- data/{lib/khronos/.version.rb.swp → spec/tmp/sqlite3.db} +0 -0
- metadata +92 -55
- data/config/.config.yml.un~ +0 -0
- data/config/.environment.yml.un~ +0 -0
- data/config/.redis.yml.un~ +0 -0
- data/config/.storage.yml.un~ +0 -0
- data/lib/.khronos.rb.un~ +0 -0
- data/lib/.scheduler.rb.un~ +0 -0
- data/lib/khronos/.config.rb.un~ +0 -0
- data/lib/khronos/.controller.rb.un~ +0 -0
- data/lib/khronos/.runner.rb.un~ +0 -0
- data/lib/khronos/.schedule.rb.un~ +0 -0
- data/lib/khronos/.scheduler.rb.un~ +0 -0
- data/lib/khronos/.server.rb.un~ +0 -0
- data/lib/khronos/.storage.rb.un~ +0 -0
- data/lib/khronos/.task.rb.un~ +0 -0
- data/lib/khronos/.version.rb.un~ +0 -0
- data/lib/khronos/controller.rb +0 -26
- data/lib/khronos/runner.rb +0 -11
- data/lib/khronos/storage/adapter/.client.rb.un~ +0 -0
- data/lib/khronos/storage/adapter/.memcached.rb.un~ +0 -0
- data/lib/khronos/storage/adapter/.mongo.rb.un~ +0 -0
- data/lib/khronos/storage/adapter/.mongodb.rb.un~ +0 -0
- data/lib/khronos/storage/adapter/.postgres.rb.un~ +0 -0
- data/lib/khronos/storage/adapter/.redis.rb.un~ +0 -0
- data/lib/khronos/storage/adapter/mongo.rb +0 -13
- data/lib/khronos/storage/adapter/mongo/.mongo.rb.un~ +0 -0
- data/lib/khronos/storage/adapter/mongo/.schedule.rb.un~ +0 -0
- data/lib/khronos/storage/adapter/postgres.rb +0 -15
- data/lib/khronos/storage/adapter/postgres/.schedule_log.rb.un~ +0 -0
- data/lib/khronos/storage/adapter/postgres/schedule.rb +0 -13
- data/lib/khronos/storage/adapter/postgres/schedule_log.rb +0 -13
- data/lib/khronos/storage/db/migrate/.schedule.rb.un~ +0 -0
- data/lib/khronos/storage/db/migrate/.schedule_log.rb.un~ +0 -0
- data/lib/khronos/storage/db/migrate/schedule.rb +0 -15
- data/lib/khronos/storage/db/migrate/schedule_log.rb +0 -16
- data/spec/.spec_helper.rb.un~ +0 -0
- data/spec/functional/.client_spec.rb.un~ +0 -0
- data/spec/functional/client_spec.rb +0 -24
- data/spec/integration/.server_spec.rb.un~ +0 -0
- data/spec/integration/server_spec.rb +0 -31
data/lib/khronos/storage.rb
CHANGED
@@ -1,26 +1,47 @@
|
|
1
|
-
require 'delegate'
|
2
1
|
require 'uri'
|
3
2
|
|
4
3
|
module Khronos
|
5
|
-
class Storage
|
6
|
-
|
4
|
+
class Storage
|
5
|
+
autoload :Adapter, 'khronos/storage/adapter'
|
7
6
|
|
8
|
-
def initialize(
|
9
|
-
|
10
|
-
@uri = URI.parse(url)
|
7
|
+
def initialize(uri=ENV['KHRONOS_STORAGE'])
|
8
|
+
raise RuntimeError.new("Please configure 'KHRONOS_STORAGE' on your environment variables.") if uri.nil?
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
@adapter = Adapter.get(uri)
|
11
|
+
self.migrate! if @adapter.name =~ /ActiveRecord/
|
12
|
+
self.class.send(:include, @adapter)
|
15
13
|
end
|
16
14
|
|
17
|
-
def
|
18
|
-
|
15
|
+
def logger=(logger)
|
16
|
+
#
|
17
|
+
# Change logger current adapter's logger
|
18
|
+
#
|
19
|
+
raise NotImplementedMethod
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
-
|
22
|
+
def truncate!
|
23
|
+
Schedule.delete_all
|
24
|
+
ScheduleLog.delete_all
|
23
25
|
end
|
24
26
|
|
27
|
+
protected
|
28
|
+
|
29
|
+
def migrate!
|
30
|
+
require 'khronos/storage/adapter/activerecord/migrations/schedule'
|
31
|
+
require 'khronos/storage/adapter/activerecord/migrations/schedule_log'
|
32
|
+
|
33
|
+
unless ActiveRecord::Base.connection.table_exists?(:schedules)
|
34
|
+
Adapter::ActiveRecord::CreateSchedule.up
|
35
|
+
else
|
36
|
+
Logger.debug "Schedules table already exists."
|
37
|
+
end
|
38
|
+
|
39
|
+
unless ActiveRecord::Base.connection.table_exists?(:schedule_logs)
|
40
|
+
Adapter::ActiveRecord::CreateScheduleLog.up
|
41
|
+
else
|
42
|
+
Logger.debug "ScheduleLog table already exists."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
25
46
|
end
|
26
47
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Khronos
|
2
|
+
class Storage
|
3
|
+
module Adapter
|
4
|
+
@frameworks = {
|
5
|
+
'mongodb' => 'mongoid',
|
6
|
+
'postgresql' => 'activerecord',
|
7
|
+
'mysql2' => 'activerecord',
|
8
|
+
'sqlite3' => 'activerecord'
|
9
|
+
}
|
10
|
+
@classes = {
|
11
|
+
'activerecord' => 'ActiveRecord',
|
12
|
+
'mongoid' => 'Mongoid'
|
13
|
+
}
|
14
|
+
@adapters = {
|
15
|
+
'mongodb' => 'mongoid'
|
16
|
+
}
|
17
|
+
|
18
|
+
def self.parse_uri(uri)
|
19
|
+
data = URI.parse(uri)
|
20
|
+
{
|
21
|
+
:scheme => data.scheme,
|
22
|
+
:host => data.host,
|
23
|
+
:user => data.user,
|
24
|
+
:password => data.password,
|
25
|
+
:path => data.path
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.get(url)
|
30
|
+
uri = parse_uri(url)
|
31
|
+
framework = @frameworks[uri[:scheme]]
|
32
|
+
|
33
|
+
require "khronos/storage/adapter/#{framework}"
|
34
|
+
|
35
|
+
# Get and connect with the adapter class.
|
36
|
+
adapter = const_get(@classes[framework])
|
37
|
+
|
38
|
+
# uri.merge(:adapter => @adapters[uri[:scheme]] || uri[:scheme])
|
39
|
+
adapter.connect!(url)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Khronos
|
4
|
+
class Storage
|
5
|
+
module Adapter
|
6
|
+
|
7
|
+
module ActiveRecord
|
8
|
+
autoload :Schedule, 'khronos/storage/adapter/activerecord/schedule'
|
9
|
+
autoload :ScheduleLog, 'khronos/storage/adapter/activerecord/schedule_log'
|
10
|
+
|
11
|
+
def self.connect!(url)
|
12
|
+
puts "Connect! => #{url.inspect}"
|
13
|
+
if File.exists?("config/database.yml")
|
14
|
+
::ActiveRecord::Base.establish_connection(YAML.load_file("config/database.yml")[ENV['RACK_ENV']])
|
15
|
+
else
|
16
|
+
::ActiveRecord::Base.establish_connection(url)
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# ::ActiveRecord::Base.logger = ::Logger.new(STDOUT)
|
21
|
+
#
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.included(base)
|
26
|
+
#puts "included in #{base}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.extended(base)
|
30
|
+
#puts "extended in #{base.inspect}"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Khronos
|
2
|
+
class Storage
|
3
|
+
module Adapter
|
4
|
+
module ActiveRecord
|
5
|
+
|
6
|
+
class CreateSchedule < ::ActiveRecord::Migration
|
7
|
+
def self.up
|
8
|
+
create_table :schedules do |t|
|
9
|
+
t.string :context, :null => false, :limit => 100
|
10
|
+
t.datetime :at, :null => false
|
11
|
+
t.string :task_url, :null => false
|
12
|
+
t.integer :recurrency, :null => false
|
13
|
+
t.string :callbacks, :null => true, :limit => 500
|
14
|
+
t.boolean :active, :null => false, :default => true
|
15
|
+
end
|
16
|
+
|
17
|
+
add_index :schedules, :at
|
18
|
+
add_index :schedules, :context
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.down
|
22
|
+
drop_table :schedules
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Khronos
|
2
|
+
class Storage
|
3
|
+
module Adapter
|
4
|
+
module ActiveRecord
|
5
|
+
|
6
|
+
class CreateScheduleLog < ::ActiveRecord::Migration
|
7
|
+
def self.up
|
8
|
+
create_table :schedule_logs do |t|
|
9
|
+
t.integer :schedule_id, :null => false
|
10
|
+
t.datetime :started_at, :null => false
|
11
|
+
t.datetime :finished_at, :null => true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table :schedule_logs
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Khronos
|
4
|
+
class Storage
|
5
|
+
module Adapter
|
6
|
+
|
7
|
+
module ActiveRecord
|
8
|
+
class Schedule < ::ActiveRecord::Base
|
9
|
+
attr_accessible :context, :at, :recurrency, :task_url, :callbacks, :active
|
10
|
+
has_many :logs, :class_name => ScheduleLog
|
11
|
+
|
12
|
+
def callbacks=(options)
|
13
|
+
write_attribute(:callbacks, options.to_json)
|
14
|
+
end
|
15
|
+
|
16
|
+
def callbacks
|
17
|
+
JSON.parse(read_attribute(:callbacks) || '{}')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'mongoid'
|
2
|
+
require 'mongo'
|
3
|
+
|
4
|
+
module Khronos
|
5
|
+
class Storage
|
6
|
+
module Adapter
|
7
|
+
|
8
|
+
module Mongoid
|
9
|
+
autoload :Schedule, 'khronos/storage/adapter/mongoid/schedule'
|
10
|
+
autoload :ScheduleLog, 'khronos/storage/adapter/mongoid/schedule_log'
|
11
|
+
|
12
|
+
def self.connect!(uri)
|
13
|
+
if File.exists?("config/mongoid.yml")
|
14
|
+
::Mongoid.load!("config/mongoid.yml")
|
15
|
+
else
|
16
|
+
::Mongoid.configure do |config|
|
17
|
+
config.connect_to uri[:host][1..-1]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(base)
|
25
|
+
#puts "included in #{base}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.extended(base)
|
29
|
+
#puts "extended in #{base.inspect}"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
@@ -1,15 +1,17 @@
|
|
1
1
|
module Khronos
|
2
|
-
|
2
|
+
class Storage
|
3
3
|
module Adapter
|
4
4
|
|
5
|
-
module
|
5
|
+
module Mongoid
|
6
6
|
class Schedule
|
7
|
-
include Mongoid::Document
|
7
|
+
include ::Mongoid::Document
|
8
8
|
|
9
9
|
field :namespace, :type => String
|
10
10
|
field :context, :type => String
|
11
11
|
field :at, :type => DateTime
|
12
|
-
field :
|
12
|
+
field :recurrency, :type => Integer
|
13
|
+
field :callbacks, :type => Hash
|
14
|
+
field :active, :type => Boolean
|
13
15
|
|
14
16
|
has_many :logs, :class_name => ScheduleLog
|
15
17
|
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
|
2
1
|
module Khronos
|
3
|
-
|
2
|
+
class Storage
|
4
3
|
module Adapter
|
5
4
|
|
6
|
-
module
|
5
|
+
module Mongoid
|
7
6
|
class ScheduleLog
|
8
|
-
include Mongoid::Document
|
7
|
+
include ::Mongoid::Document
|
9
8
|
|
10
9
|
field :started_at, :type => DateTime
|
11
10
|
field :finished_at, :type => DateTime
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'khronos/storage/adapter/activerecord/migrations/schedule'
|
2
|
+
require 'khronos/storage/adapter/activerecord/migrations/schedule_log'
|
3
|
+
|
4
|
+
namespace :db do
|
5
|
+
|
6
|
+
desc 'Create the database.'
|
7
|
+
task :create do
|
8
|
+
adapter = Khronos::Storage::Adapter.get(ENV['KHRONOS_STORAGE'])
|
9
|
+
if adapter.name =~ /ActiveRecord/
|
10
|
+
CreateSchedule.up
|
11
|
+
CreateScheduleLog.up
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Destroy entire database.'
|
16
|
+
task :drop do
|
17
|
+
adapter = Khronos::Storage::Adapter.get(ENV['KHRONOS_STORAGE'])
|
18
|
+
if adapter.name =~ /ActiveRecord/
|
19
|
+
CreateSchedule.down
|
20
|
+
CreateScheduleLog.down
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
data/lib/khronos/version.rb
CHANGED
data/server.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
$: << 'lib'
|
2
|
+
ENV['RACK_ENV'] = 'development'
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'active_support/all'
|
7
|
+
require 'khronos'
|
8
|
+
|
9
|
+
#controller = Khronos::Controller.new
|
10
|
+
#controller.start!
|
11
|
+
|
12
|
+
case ARGV[0]
|
13
|
+
when 'runner'
|
14
|
+
puts "Running: Runner."
|
15
|
+
|
16
|
+
require 'khronos/server/runner'
|
17
|
+
EventMachine.run {
|
18
|
+
EventMachine.start_server Khronos::Config.instance.runner['host'], Khronos::Config.instance.runner['port'], Khronos::Server::Runner
|
19
|
+
}
|
20
|
+
|
21
|
+
when 'scheduler'
|
22
|
+
puts "Running: Scheduler."
|
23
|
+
run Khronos::Server::Scheduler
|
24
|
+
|
25
|
+
when 'controller'
|
26
|
+
controller = Khronos::Controller.new
|
27
|
+
controller.start!
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Khronos::Storage do
|
4
|
+
subject { Khronos::Storage }
|
5
|
+
|
6
|
+
describe Khronos::Storage::Adapter do
|
7
|
+
|
8
|
+
it "should identify activerecord adapter for postgres" do
|
9
|
+
client = subject.new('postgresql://localhost:5432/khronos')
|
10
|
+
Khronos::Storage::Schedule.should == Khronos::Storage::Adapter::ActiveRecord::Schedule
|
11
|
+
Khronos::Storage::ScheduleLog.should == Khronos::Storage::Adapter::ActiveRecord::ScheduleLog
|
12
|
+
Khronos::Storage::Schedule.create({
|
13
|
+
:context => "test:dummy",
|
14
|
+
:task_url => "http://some-service.com/task",
|
15
|
+
:at => Time.now,
|
16
|
+
:recurrency => 1.day
|
17
|
+
})
|
18
|
+
Khronos::Storage::Schedule.last.task_url.should == "http://some-service.com/task"
|
19
|
+
end
|
20
|
+
|
21
|
+
xit "should identify activerecord adapter for mysql" do
|
22
|
+
client = subject.new('mysql2://localhost:3306/khronos')
|
23
|
+
Khronos::Storage::Schedule.should == Khronos::Storage::Adapter::ActiveRecord::Schedule
|
24
|
+
Khronos::Storage::ScheduleLog.should == Khronos::Storage::Adapter::ActiveRecord::ScheduleLog
|
25
|
+
Khronos::Storage::Schedule.create({
|
26
|
+
:context => "test:dummy",
|
27
|
+
:task_url => "http://some-service.com/task",
|
28
|
+
:at => Time.now,
|
29
|
+
:recurrency => 1.day
|
30
|
+
})
|
31
|
+
Khronos::Storage::Schedule.last.task_url.should == "http://some-service.com/task"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should identify activerecord adapter for sqlite3" do
|
35
|
+
client = subject.new('sqlite3://localhost/spec/tmp/sqlite3.db')
|
36
|
+
Khronos::Storage::Schedule.should == Khronos::Storage::Adapter::ActiveRecord::Schedule
|
37
|
+
Khronos::Storage::ScheduleLog.should == Khronos::Storage::Adapter::ActiveRecord::ScheduleLog
|
38
|
+
Khronos::Storage::Schedule.create({
|
39
|
+
:context => "test:dummy",
|
40
|
+
:task_url => "http://some-service.com/task",
|
41
|
+
:at => Time.now,
|
42
|
+
:recurrency => 1.day
|
43
|
+
})
|
44
|
+
Khronos::Storage::Schedule.last.task_url.should == "http://some-service.com/task"
|
45
|
+
end
|
46
|
+
|
47
|
+
xit "should identify mongodb adapter" do
|
48
|
+
client = subject.new('mongodb://127.0.0.1:6379/test')
|
49
|
+
Khronos::Storage::Schedule.should == Khronos::Storage::Adapter::Mongoid::Schedule
|
50
|
+
Khronos::Storage::ScheduleLog.should == Khronos::Storage::Adapter::Mongoid::ScheduleLog
|
51
|
+
Khronos::Storage::Schedule.create({
|
52
|
+
:context => "test:dummy",
|
53
|
+
:task_url => "http://some-service.com/task",
|
54
|
+
:at => Time.now,
|
55
|
+
:recurrency => 1.day
|
56
|
+
})
|
57
|
+
Khronos::Storage::Schedule.last.task_url.should == "http://some-service.com/task"
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|