level_up 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.txt +2 -0
- data/LICENSE.txt +20 -0
- data/README.md +190 -0
- data/Rakefile +40 -0
- data/app/assets/images/level_up/search.png +0 -0
- data/app/assets/javascripts/level_up/application.js +15 -0
- data/app/assets/javascripts/level_up/home.js +2 -0
- data/app/assets/javascripts/level_up/jobs.js +2 -0
- data/app/assets/stylesheets/level_up/application.css.scss +446 -0
- data/app/assets/stylesheets/level_up/home.css.scss +119 -0
- data/app/assets/stylesheets/level_up/jobs.css.scss +159 -0
- data/app/assets/stylesheets/level_up/rwdgrid.css +403 -0
- data/app/controllers/level_up/application_controller.rb +4 -0
- data/app/controllers/level_up/home_controller.rb +22 -0
- data/app/controllers/level_up/jobs_controller.rb +117 -0
- data/app/helpers/level_up/application_helper.rb +7 -0
- data/app/helpers/level_up/home_helper.rb +7 -0
- data/app/helpers/level_up/jobs_helper.rb +4 -0
- data/app/models/level_up/job.rb +212 -0
- data/app/models/level_up/state/cancel.rb +7 -0
- data/app/models/level_up/state/end.rb +7 -0
- data/app/models/level_up/state/start.rb +9 -0
- data/app/models/level_up/state.rb +53 -0
- data/app/views/layouts/level_up/_footer.html.erb +9 -0
- data/app/views/layouts/level_up/_header.html.erb +23 -0
- data/app/views/layouts/level_up/application.html.erb +36 -0
- data/app/views/level_up/home/index.html.erb +85 -0
- data/app/views/level_up/home/workflow.html.erb +5 -0
- data/app/views/level_up/jobs/edit.html.erb +65 -0
- data/app/views/level_up/jobs/index.html.erb +73 -0
- data/app/views/level_up/jobs/show.html.erb +93 -0
- data/config/routes.rb +13 -0
- data/db/migrate/20130212111454_create_level_up_jobs.rb +27 -0
- data/lib/level_up/configuration.rb +27 -0
- data/lib/level_up/engine.rb +17 -0
- data/lib/level_up/version.rb +3 -0
- data/lib/level_up.rb +7 -0
- data/lib/tasks/level_up_tasks.rake +4 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/account_banish.rb +18 -0
- data/test/dummy/app/jobs/account_downgrade.rb +13 -0
- data/test/dummy/app/jobs/account_upgrade.rb +15 -0
- data/test/dummy/app/jobs/mailing_list_subscription.rb +15 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/migrate/20130212113009_create_delayed_jobs.rb +22 -0
- data/test/dummy/db/migrate/20130215111404_create_level_up_jobs.level_up.rb +28 -0
- data/test/dummy/db/schema.rb +57 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/delayed_job +5 -0
- data/test/dummy/script/rails +6 -0
- data/test/fixtures/level_up/jobs.yml +11 -0
- data/test/functional/level_up/home_controller_test.rb +9 -0
- data/test/functional/level_up/jobs_controller_test.rb +9 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/level_up_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/helpers/level_up/home_helper_test.rb +6 -0
- data/test/unit/helpers/level_up/jobs_helper_test.rb +6 -0
- data/test/unit/level_up/job_test.rb +208 -0
- metadata +333 -0
data/CHANGELOG.txt
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 Karim Matrah
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
# LevelUp: a Rails engine to keep your startup technical business organized.
|
2
|
+
|
3
|
+
##[Documentation](http://kmatrah.github.com/level_up)
|
4
|
+
|
5
|
+
## What ?
|
6
|
+
|
7
|
+
If you are building a web app, chances are good you have some jobs to design and execute in order to provide services to your customers.
|
8
|
+
Generally, that means handling automated tasks, manual human tasks, calls to external services, failures, timers and retries.
|
9
|
+
LevelUp lets you build all of these and compose them to create a runnable job. Concretely, you will define a state graph, where each state
|
10
|
+
represents a task and contains its own business logic implemented in ruby. Jobs can be performed synchronously in the
|
11
|
+
current thread or asynchronously by background workers. Three methods are available in each state to control the job flow: move_to(new_state), retry_in(delay), manual_task(task_description).
|
12
|
+
|
13
|
+
## Why use LevelUp ?
|
14
|
+
|
15
|
+
Designing your jobs graphically with states and transitions can be more easier than directly writing code, especially for non-technical people.
|
16
|
+
Graphs can be drawn, printed, shared and analysed making it easier to let everyone know what the system is doing at specific points in time.
|
17
|
+
From a developers point of view, it’s clearer to separate the different parts of a job into isolated states. Class based states are reusable
|
18
|
+
in multiple jobs to avoid code duplication. For example, you can use the Template design pattern to implement the generic part of a state
|
19
|
+
in a parent class and implement specialized parts in children classes.
|
20
|
+
|
21
|
+
## Requirements
|
22
|
+
Ruby 1.9+, Rails 3.2.x, ActiveRecord, DelayedJob 3.x
|
23
|
+
|
24
|
+
## Installation
|
25
|
+
|
26
|
+
Add LevelUp to your Gemfile:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
gem 'level_up'
|
30
|
+
```
|
31
|
+
|
32
|
+
and run `bundle install` within your app's directory.
|
33
|
+
|
34
|
+
## Run Migrations
|
35
|
+
|
36
|
+
First, make sure DelayedJob migration is installed. If not:
|
37
|
+
|
38
|
+
```bash
|
39
|
+
$ rails g delayed_job:active_record
|
40
|
+
```
|
41
|
+
|
42
|
+
Install and run LevelUp migration:
|
43
|
+
|
44
|
+
```bash
|
45
|
+
$ rake level_up:install:migrations
|
46
|
+
$ rake db:migrate
|
47
|
+
```
|
48
|
+
|
49
|
+
## Mount the engine
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# config/routes.rb
|
53
|
+
Rails.application.routes.draw do
|
54
|
+
# ...
|
55
|
+
mount LevelUp::Engine => "/level_up"
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
## Authentication
|
60
|
+
|
61
|
+
LevelUp only provide basic http authentication through Rails 3.1+ <em>http_basic_authenticate_with</em> method. Authentication is disabled by
|
62
|
+
default. To enable it, add these lines in your config/environments/*.rb.
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
# config/environments/*.rb
|
66
|
+
config.level_up.http_authentication = true
|
67
|
+
config.level_up.http_login = "your-login"
|
68
|
+
config.level_up.http_password = "your-password"
|
69
|
+
```
|
70
|
+
|
71
|
+
## Writing Job Models
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# app/jobs/hard_job.rb
|
75
|
+
class HardJob < LevelUp::Job
|
76
|
+
# states and transitions
|
77
|
+
job do
|
78
|
+
state :start, moves_to: :first_task
|
79
|
+
state :first_task, moves_to: :second_task
|
80
|
+
state :second_task, moves_to: :end
|
81
|
+
end
|
82
|
+
|
83
|
+
def first_task
|
84
|
+
# logic goes here
|
85
|
+
end
|
86
|
+
|
87
|
+
def second_task
|
88
|
+
# logic goes here
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
### State objects
|
94
|
+
|
95
|
+
You can also define state logic in a class instead of a method.
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
app/jobs/hard_job/first_task.rb
|
99
|
+
module HardJob
|
100
|
+
class FirstTask < LevelUp::State
|
101
|
+
def run
|
102
|
+
# logic goes here
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
app/jobs/hard_job/second_task.rb
|
110
|
+
module HardJob
|
111
|
+
class SecondTask < LevelUp::State
|
112
|
+
def run
|
113
|
+
# logic goes here
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
### Flow control
|
120
|
+
|
121
|
+
Inside a state, you can call 3 methods to control the job flow:
|
122
|
+
|
123
|
+
#### move_to(state_name)
|
124
|
+
|
125
|
+
Leave the current state and run the specified state.
|
126
|
+
```ruby
|
127
|
+
# example:
|
128
|
+
move_to :second_task
|
129
|
+
```
|
130
|
+
|
131
|
+
#### retry_in(delay)
|
132
|
+
|
133
|
+
Stop the execution and queue a new delayed_job to re-run the current state after the specified delay in seconds.
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
# example:
|
137
|
+
retry_in 1.hour
|
138
|
+
```
|
139
|
+
|
140
|
+
#### task(description)
|
141
|
+
Stop the execution and set the task and task_description attributes to notify a manual human intervention.
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
# example:
|
145
|
+
task "check payment information"
|
146
|
+
```
|
147
|
+
|
148
|
+
You can also raise a StandardError (or a subclass) to stop the execution and set the error attribute.
|
149
|
+
The time, the state and the error backtrace will be saved.
|
150
|
+
|
151
|
+
## Running Jobs
|
152
|
+
In your code:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
job = HardJob.create(key: "job-key")
|
156
|
+
|
157
|
+
# execute the job synchronously
|
158
|
+
job.boot
|
159
|
+
|
160
|
+
# or asynchronously with DelayedJob
|
161
|
+
job.boot_async!
|
162
|
+
```
|
163
|
+
|
164
|
+
## Todo
|
165
|
+
- Others authentication methods
|
166
|
+
- More metrics and filters in the dashboard
|
167
|
+
- Remove the dependency on DelayedJob to allow the use of others asynchronous queue systems like Resque, Sidekiq or Beanstalk
|
168
|
+
- Allow graphical interaction on SVG graphs to manage jobs
|
169
|
+
- ...
|
170
|
+
|
171
|
+
## Contributing to LevelUp
|
172
|
+
|
173
|
+
Your feedback is very welcome and will make this gem much much better for you, me and everyone else.
|
174
|
+
Besides feedback on code, features, suggestions and bug reports, you may want to actually make an impact on the code. For this:
|
175
|
+
|
176
|
+
- Fork it.
|
177
|
+
- Fix it.
|
178
|
+
- Test it.
|
179
|
+
- Commit it.
|
180
|
+
- Send me a pull request.
|
181
|
+
|
182
|
+
## Contact
|
183
|
+
|
184
|
+
Feel free to ask questions using these contact details:
|
185
|
+
- email: karim.matrah@gmail.com
|
186
|
+
- twitter: @kmatrah
|
187
|
+
|
188
|
+
## Copyright
|
189
|
+
|
190
|
+
Copyright 2013 Karim Matrah. See LICENSE.txt for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'LevelUp'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << 'lib'
|
34
|
+
t.libs << 'test'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
Binary file
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require_tree .
|