untied 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/.gitignore +20 -0
  2. data/.rvmrc +48 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +7 -0
  6. data/README.md +124 -0
  7. data/Rakefile +3 -0
  8. data/bin/untied_worker +16 -0
  9. data/examples/goliath/.rvmrc +48 -0
  10. data/examples/goliath/Gemfile +9 -0
  11. data/examples/goliath/README.mkd +81 -0
  12. data/examples/goliath/Rakefile +14 -0
  13. data/examples/goliath/config/srv.rb +21 -0
  14. data/examples/goliath/models/user.rb +5 -0
  15. data/examples/goliath/observer.rb +10 -0
  16. data/examples/goliath/srv.rb +46 -0
  17. data/examples/rails-consumer/.rvmrc +48 -0
  18. data/examples/rails-consumer/Gemfile +38 -0
  19. data/examples/rails-consumer/README.mkd +37 -0
  20. data/examples/rails-consumer/Rakefile +7 -0
  21. data/examples/rails-consumer/app/assets/images/rails.png +0 -0
  22. data/examples/rails-consumer/app/assets/javascripts/application.js +15 -0
  23. data/examples/rails-consumer/app/assets/javascripts/users.js.coffee +3 -0
  24. data/examples/rails-consumer/app/assets/stylesheets/application.css +13 -0
  25. data/examples/rails-consumer/app/assets/stylesheets/scaffolds.css.scss +69 -0
  26. data/examples/rails-consumer/app/assets/stylesheets/users.css.scss +3 -0
  27. data/examples/rails-consumer/app/controllers/application_controller.rb +3 -0
  28. data/examples/rails-consumer/app/controllers/users_controller.rb +83 -0
  29. data/examples/rails-consumer/app/helpers/application_helper.rb +2 -0
  30. data/examples/rails-consumer/app/helpers/users_helper.rb +2 -0
  31. data/examples/rails-consumer/app/mailers/.gitkeep +0 -0
  32. data/examples/rails-consumer/app/models/.gitkeep +0 -0
  33. data/examples/rails-consumer/app/models/untied_user_observer.rb +8 -0
  34. data/examples/rails-consumer/app/models/user.rb +3 -0
  35. data/examples/rails-consumer/app/views/layouts/application.html.erb +14 -0
  36. data/examples/rails-consumer/app/views/users/_form.html.erb +21 -0
  37. data/examples/rails-consumer/app/views/users/edit.html.erb +6 -0
  38. data/examples/rails-consumer/app/views/users/index.html.erb +23 -0
  39. data/examples/rails-consumer/app/views/users/new.html.erb +5 -0
  40. data/examples/rails-consumer/app/views/users/show.html.erb +10 -0
  41. data/examples/rails-consumer/config/application.rb +62 -0
  42. data/examples/rails-consumer/config/boot.rb +6 -0
  43. data/examples/rails-consumer/config/database.yml +25 -0
  44. data/examples/rails-consumer/config/environment.rb +5 -0
  45. data/examples/rails-consumer/config/environments/development.rb +37 -0
  46. data/examples/rails-consumer/config/environments/production.rb +67 -0
  47. data/examples/rails-consumer/config/environments/test.rb +37 -0
  48. data/examples/rails-consumer/config/initializers/backtrace_silencers.rb +7 -0
  49. data/examples/rails-consumer/config/initializers/inflections.rb +15 -0
  50. data/examples/rails-consumer/config/initializers/mime_types.rb +5 -0
  51. data/examples/rails-consumer/config/initializers/secret_token.rb +7 -0
  52. data/examples/rails-consumer/config/initializers/session_store.rb +8 -0
  53. data/examples/rails-consumer/config/initializers/untied.rb +4 -0
  54. data/examples/rails-consumer/config/initializers/wrap_parameters.rb +14 -0
  55. data/examples/rails-consumer/config/locales/en.yml +5 -0
  56. data/examples/rails-consumer/config/routes.rb +60 -0
  57. data/examples/rails-consumer/config.ru +4 -0
  58. data/examples/rails-consumer/db/development.sqlite3 +0 -0
  59. data/examples/rails-consumer/db/migrate/20121019155057_create_users.rb +9 -0
  60. data/examples/rails-consumer/db/schema.rb +22 -0
  61. data/examples/rails-consumer/db/seeds.rb +7 -0
  62. data/examples/rails-consumer/lib/assets/.gitkeep +0 -0
  63. data/examples/rails-consumer/lib/tasks/.gitkeep +0 -0
  64. data/examples/rails-consumer/log/.gitkeep +0 -0
  65. data/examples/rails-consumer/log/development.log +135 -0
  66. data/examples/rails-consumer/public/404.html +26 -0
  67. data/examples/rails-consumer/public/422.html +26 -0
  68. data/examples/rails-consumer/public/500.html +25 -0
  69. data/examples/rails-consumer/public/favicon.ico +0 -0
  70. data/examples/rails-consumer/public/index.html +241 -0
  71. data/examples/rails-consumer/public/robots.txt +5 -0
  72. data/examples/rails-consumer/script/rails +6 -0
  73. data/examples/rails-consumer/test/fixtures/.gitkeep +0 -0
  74. data/examples/rails-consumer/test/fixtures/users.yml +7 -0
  75. data/examples/rails-consumer/test/functional/.gitkeep +0 -0
  76. data/examples/rails-consumer/test/functional/users_controller_test.rb +49 -0
  77. data/examples/rails-consumer/test/integration/.gitkeep +0 -0
  78. data/examples/rails-consumer/test/performance/browsing_test.rb +12 -0
  79. data/examples/rails-consumer/test/test_helper.rb +13 -0
  80. data/examples/rails-consumer/test/unit/.gitkeep +0 -0
  81. data/examples/rails-consumer/test/unit/helpers/users_helper_test.rb +4 -0
  82. data/examples/rails-consumer/test/unit/user_test.rb +7 -0
  83. data/examples/rails-consumer/vendor/assets/javascripts/.gitkeep +0 -0
  84. data/examples/rails-consumer/vendor/assets/stylesheets/.gitkeep +0 -0
  85. data/examples/rails-consumer/vendor/plugins/.gitkeep +0 -0
  86. data/examples/social_network.rb +1 -0
  87. data/lib/untied/version.rb +4 -0
  88. data/lib/untied.rb +20 -0
  89. data/spec/spec_helper.rb +28 -0
  90. data/spec/support/setup_ar_and_schema.rb +24 -0
  91. data/untied.gemspec +25 -0
  92. metadata +212 -0
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.swp
19
+ *.swo
20
+ .rspec
data/.rvmrc ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
+ # Only full ruby name is supported here, for short names use:
8
+ # echo "rvm use 1.8.7" > .rvmrc
9
+ environment_id="ruby-1.8.7-p370"
10
+
11
+ # Uncomment the following lines if you want to verify rvm version per project
12
+ # rvmrc_rvm_version="1.14.5 (master)" # 1.10.1 seams as a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+
18
+ # First we attempt to load the desired environment directly from the environment
19
+ # file. This is very fast and efficient compared to running through the entire
20
+ # CLI and selector. If you want feedback on which environment was used then
21
+ # insert the word 'use' after --create as this triggers verbose mode.
22
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
+ then
25
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
+ [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
+ \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
+ else
29
+ # If the environment file has not yet been created, use the RVM CLI to select.
30
+ rvm --create "$environment_id" || {
31
+ echo "Failed to create RVM environment '${environment_id}'."
32
+ return 1
33
+ }
34
+ fi
35
+
36
+ # If you use bundler, this might be useful to you:
37
+ # if [[ -s Gemfile ]] && {
38
+ # ! builtin command -v bundle >/dev/null ||
39
+ # builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
40
+ # }
41
+ # then
42
+ # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
43
+ # gem install bundler
44
+ # fi
45
+ # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
46
+ # then
47
+ # bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
48
+ # fi
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - 1.8.7
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in untied.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2012 Redu Educational Technologies
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # Untied
2
+
3
+ Need to register an Observer which observes ActiveRecord models in different applications? Untied Observer for the rescue.
4
+
5
+ The publisher application registers which models are able to be observed. The consumers just need to define callbacks that will be fired for certain events. The consumer part uses an API similar to the one provided by ActiveRecord::Observer.
6
+
7
+ **Build status**
8
+
9
+ - Untied::Consumer [![Build Status](https://travis-ci.org/redu/untied-consumer.png)](https://travis-ci.org/redu/untied-consumer)
10
+ - Untied::Publisher [![Build Status](https://travis-ci.org/redu/untied-publisher.png)](https://travis-ci.org/redu/untied-publisher)
11
+
12
+ ### Publisher
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ gem 'untied'
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install untied
27
+
28
+ The untied Gem relies on RabbitMQ, so it need to be installed in order to work properly. [Here are](http://www.rabbitmq.com/download.html) the instructions.
29
+
30
+ ## Usage
31
+
32
+ ### Publisher
33
+
34
+ You need to do some configurations on the publisher side:
35
+
36
+ ```ruby
37
+ Untied::Publisher.configure do |config|
38
+ config.logger = Logger.new(STDOUT)
39
+ config.deliver_messages = true # Silent mode when falsy
40
+ config.service_name = "social-network"
41
+ config.doorkeeper = MyDoorkeeper
42
+ end
43
+ ```
44
+
45
+ The ``service_name`` configuration is very important here. It must be unique across all the services and will be used to uniquely identify the models. The ``deliver_messages``option enable and disable events sending. Disabling it may be useful on test and development environment.
46
+
47
+ The ``doorkeeper`` configuration let you specify which class is responsible for telling which ActiveRecord models are capable of be observed.
48
+
49
+ You should also define when the ActiveRecord models will be propagated to other services. We can take advantage on the usefulness of ``ActiveRecord::Callbacks``. To keep the things DRY, this job may be done inside what we call the Watcher:
50
+
51
+ ```ruby
52
+ class MyDoorkeeper
53
+ include Untied::Doorkeeper
54
+
55
+ def initialize
56
+ watch User, :after_create, :after_update
57
+ end
58
+ end
59
+ ```
60
+
61
+ The watcher defined above will propagate Users instances when they are created or updated.
62
+
63
+ ### Consumer
64
+
65
+ On the consumer side, you just need to define the observer as you would with ActiveRecord::Observer. Remember to subclass Untied::Observer instead.
66
+
67
+ ```ruby
68
+ class UserObserver < Untied::Consumer::Observer
69
+ observe :user, :from => "social-network"
70
+
71
+ def after_create(user)
72
+ puts "A the following user was created on social-network service: #{user}"
73
+ end
74
+
75
+ def after_update(user)
76
+ puts "A the following user was updated on social-network service: #{user}"
77
+ end
78
+ end
79
+ ```
80
+
81
+ One important step is identify which service models the observer is listening to. That's why we user the ``:from`` option on the ``observe`` method.
82
+
83
+ Activating observers:
84
+
85
+ ```ruby
86
+ Untied::Consumer.configure do |config|
87
+ config.observers = [UserObserver]
88
+ end
89
+ ```
90
+
91
+ ## Internals
92
+
93
+ TODO
94
+
95
+ ## What need to be done?
96
+
97
+ - Make it ActiveRecord independent.
98
+ - Add instructions about how to initialize the worker.
99
+ - Failsafeness
100
+ - Do not rely on Pub class name
101
+
102
+
103
+ ## Contributing
104
+
105
+ 1. Fork it
106
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
107
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
108
+ 4. Push to the branch (`git push origin my-new-feature`)
109
+ 5. Create new Pull Request
110
+
111
+
112
+ <img src="https://github.com/downloads/redu/redupy/redutech-marca.png" alt="Redu Educational Technologies" width="300">
113
+
114
+ This project is maintained and funded by [Redu Educational Techologies](http://tech.redu.com.br).
115
+
116
+ # Copyright
117
+
118
+ Copyright (c) 2012 Redu Educational Technologies
119
+
120
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
121
+
122
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
123
+
124
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ Bundler::GemHelper.install_tasks
data/bin/untied_worker ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "amqp"
4
+
5
+ require "untied"
6
+ require "untied/worker"
7
+
8
+ module Untied
9
+ AMQP.start do |connection|
10
+ channel = AMQP::Channel.new(connection)
11
+ exchange = channel.topic("untied", :auto_delete => true)
12
+ # consumer = Consumer.new
13
+ worker = Consumer::Worker.new(:channel => channel, :exchange => exchange)
14
+ worker.start
15
+ end
16
+ end
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
+ # Only full ruby name is supported here, for short names use:
8
+ # echo "rvm use 1.9.2" > .rvmrc
9
+ environment_id="ruby-1.9.2-p320"
10
+
11
+ # Uncomment the following lines if you want to verify rvm version per project
12
+ # rvmrc_rvm_version="1.14.5 (master)" # 1.10.1 seams as a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+
18
+ # First we attempt to load the desired environment directly from the environment
19
+ # file. This is very fast and efficient compared to running through the entire
20
+ # CLI and selector. If you want feedback on which environment was used then
21
+ # insert the word 'use' after --create as this triggers verbose mode.
22
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
+ then
25
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
+ [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
+ \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
+ else
29
+ # If the environment file has not yet been created, use the RVM CLI to select.
30
+ rvm --create "$environment_id" || {
31
+ echo "Failed to create RVM environment '${environment_id}'."
32
+ return 1
33
+ }
34
+ fi
35
+
36
+ # If you use bundler, this might be useful to you:
37
+ # if [[ -s Gemfile ]] && {
38
+ # ! builtin command -v bundle >/dev/null ||
39
+ # builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
40
+ # }
41
+ # then
42
+ # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
43
+ # gem install bundler
44
+ # fi
45
+ # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
46
+ # then
47
+ # bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
48
+ # fi
@@ -0,0 +1,9 @@
1
+ # A sample Gemfile
2
+ source "https://rubygems.org"
3
+
4
+ gem 'goliath'
5
+ gem 'em-synchrony'
6
+ gem 'sqlite3'
7
+ gem 'activerecord'
8
+ gem 'untied', :git => 'git://github.com/redu/untied.git'
9
+ gem 'rake'
@@ -0,0 +1,81 @@
1
+ ## Using Untied with Goliath
2
+
3
+ This example defines both the Producer and the Consumer. The producer is defined inside srv.rb, which is a goliath server. The consumer doesn't depend on the producer in any way.
4
+
5
+ ### Setup
6
+
7
+ ```sh
8
+ $ > git clone git://github.com/redu/untied.git
9
+ $ > cd untied/examples/goliath
10
+ $ > bundle install
11
+ ```
12
+
13
+ The Untied gem relies on RabbitMQ, so it need to be installed in order to work properly. [Here are](http://www.rabbitmq.com/download.html) the instructions.
14
+
15
+ ### Structure
16
+
17
+ ```sh
18
+ .
19
+ ├── Gemfile
20
+ ├── Gemfile.lock
21
+ ├── README.mkd
22
+ ├── Rakefile # Requires the observer.rb. Listens on the message bus.
23
+ ├── config
24
+ │   └── srv.rb # ActiveRecord and Untied Publisher configurations
25
+ ├── models
26
+ │   └── user.rb # ActiveRecord User model
27
+ ├── observer.rb # Untied observer used by consumer
28
+ └── srv.rb # Goliath server and Untied::Doorkeeper
29
+ ```
30
+
31
+ ### More info
32
+
33
+ If you don't know what some of the components above means, here are some references:
34
+
35
+ - [Untied::Observer](https://github.com/redu/untied#consumer)
36
+ - [Untied publisher configurations](https://github.com/redu/untied#publisher)
37
+ - [Goliath](http://postrank-labs.github.com/goliath/)
38
+ - [Goliath configurarions](https://github.com/postrank-labs/goliath/wiki/Configuration)
39
+
40
+ ### Usage
41
+
42
+ #### Publisher
43
+
44
+ The publisher consists of a REST API defined as a Goliath server. Every time an User is created using this API the Untied publisher will serialize it and deliver it through the message bus.
45
+
46
+ All you need is to initialize goliath server
47
+
48
+ ```sh
49
+ goliath (master) > ruby srv.rb -sv
50
+ I, [2012-10-18T10:06:50.806799 #9274] INFO -- : Untied: Initializing publisher observer
51
+ [9274:INFO] 2012-10-18 10:06:50 :: Starting server on 0.0.0.0:9000 in development mode. Watch out for stones.
52
+ -- create_table(:users, {:force=>true})
53
+ -> 0.0158s
54
+ ```
55
+
56
+ And use the REST API:
57
+
58
+ ```sh
59
+ goliath (master) > curl http://0.0.0.0:9000?name=guila -X POST
60
+ "{\"user\":{\"created_at\":\"2012-10-18T09:59:14-03:00\",\"id\":1,\"name\":\"guila\",\"updated_at\":\"2012-10-18T09:59:14-03:00\"}}"
61
+ ```
62
+
63
+ #### Consumer
64
+
65
+ The consumer listens to the events sent to the message bus and fires defined Untied::Observer methods. In this example we just defined an ``after_create`` method for the User entity (see observer.rb).
66
+
67
+ To initialize the cosumer call the following rake task:
68
+
69
+ ```sh
70
+ goliath (master) > rake untied:consumer:work
71
+ I, [2012-10-18T10:09:44.687311 #9327] INFO -- : Worker initialized and listening
72
+ ```
73
+
74
+ Everytime an user is created on the publisher side, the consumer will process the event and call the proper callback (defined in observer.rb):
75
+
76
+ ```
77
+ # I, [2012-10-18T09:59:14.927815 #9133] INFO -- : Untied::Consumer: processing event after_create from goliath with payload {:user=>{:created_at=>"2012-10-18T09:59:14-03:00", :id=>1, :name=>"guila", :updated_at=>"2012-10-18T09:59:14-03:00"}}
78
+ # An user was created on Goliath server, yay!
79
+ ```
80
+
81
+ Of course you should consume events produced by other server, say a Rails server.
@@ -0,0 +1,14 @@
1
+ $: << File.dirname(__FILE__)
2
+
3
+ require "bundler/setup"
4
+ require "untied"
5
+ require "untied-consumer"
6
+
7
+ require "./observer"
8
+
9
+ # Enabling the observer defined in observer.rb
10
+ Untied::Consumer.configure do |c|
11
+ c.observers = [Observer]
12
+ end
13
+
14
+ load "untied-consumer/tasks/untied.tasks"
@@ -0,0 +1,21 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'em-synchrony/activerecord'
3
+
4
+ CONFIG = { Goliath.env.to_sym => { :adapter => 'sqlite3', :database => ":memory:" } }
5
+ ActiveRecord::Base.configurations = CONFIG
6
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[Goliath.env])
7
+
8
+ ActiveRecord::Schema.define do
9
+ create_table :users, :force => true do |t|
10
+ t.string :name
11
+ t.timestamp :created_at
12
+ t.timestamp :updated_at
13
+ end
14
+ end
15
+
16
+ Untied::Publisher.configure do |config|
17
+ config.logger = Logger.new(STDOUT)
18
+ config.deliver_messages = true
19
+ config.service_name = "goliath"
20
+ config.doorkeeper = "Doorkeeper"
21
+ end
@@ -0,0 +1,5 @@
1
+ # -*- encoding : utf-8 -*-
2
+ class User < ActiveRecord::Base
3
+ attr_accessible :name
4
+ end
5
+
@@ -0,0 +1,10 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # Here you should define the method which are going to be called when the
3
+ # publisher sends some event.
4
+ class Observer < Untied::Consumer::Observer
5
+ observe :user, :from => :goliath
6
+
7
+ def after_create(model)
8
+ puts "An user was created on Goliath server, yay!"
9
+ end
10
+ end
@@ -0,0 +1,46 @@
1
+ # -*- encoding : utf-8 -*-
2
+ $: << File.dirname(__FILE__)
3
+
4
+ require 'bundler/setup'
5
+ require 'goliath'
6
+ require 'em-synchrony/activerecord'
7
+ require 'untied'
8
+ require 'untied-publisher'
9
+
10
+ require 'models/user'
11
+
12
+ # Defining which ActiveRecord lifecycle events will be observed
13
+ class Doorkeeper
14
+ include Untied::Publisher::Doorkeeper
15
+
16
+ def initialize
17
+ # Everytime the User's after_create is fired, it will send the user
18
+ # through the message bus
19
+ watch User, :after_create
20
+ end
21
+ end
22
+
23
+ Untied::Publisher.config.doorkeeper = Doorkeeper
24
+
25
+ # Initializing the publisher observer
26
+ Untied::Publisher::Observer.instance
27
+
28
+ class Srv < Goliath::API
29
+ use Goliath::Rack::Params
30
+ use Goliath::Rack::DefaultMimeType
31
+ use Goliath::Rack::Render, 'json'
32
+
33
+ def response(env)
34
+ if env['REQUEST_METHOD'] == 'GET'
35
+ begin
36
+ user = User.find(params['id'])
37
+ [200, {}, user.to_json]
38
+ rescue ActiveRecord::RecordNotFound => e
39
+ [404, {}, {:error => e.message}.to_json]
40
+ end
41
+ else
42
+ user = User.create(params)
43
+ [200, {}, user.to_json]
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
+ # Only full ruby name is supported here, for short names use:
8
+ # echo "rvm use 1.9.3" > .rvmrc
9
+ environment_id="ruby-1.9.3-p194"
10
+
11
+ # Uncomment the following lines if you want to verify rvm version per project
12
+ # rvmrc_rvm_version="1.14.5 (master)" # 1.10.1 seams as a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+
18
+ # First we attempt to load the desired environment directly from the environment
19
+ # file. This is very fast and efficient compared to running through the entire
20
+ # CLI and selector. If you want feedback on which environment was used then
21
+ # insert the word 'use' after --create as this triggers verbose mode.
22
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
+ then
25
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
+ [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
+ \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
+ else
29
+ # If the environment file has not yet been created, use the RVM CLI to select.
30
+ rvm --create "$environment_id" || {
31
+ echo "Failed to create RVM environment '${environment_id}'."
32
+ return 1
33
+ }
34
+ fi
35
+
36
+ # If you use bundler, this might be useful to you:
37
+ # if [[ -s Gemfile ]] && {
38
+ # ! builtin command -v bundle >/dev/null ||
39
+ # builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
40
+ # }
41
+ # then
42
+ # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
43
+ # gem install bundler
44
+ # fi
45
+ # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
46
+ # then
47
+ # bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
48
+ # fi
@@ -0,0 +1,38 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '3.2.8'
4
+
5
+ # Bundle edge Rails instead:
6
+ # gem 'rails', :git => 'git://github.com/rails/rails.git'
7
+
8
+ gem 'sqlite3'
9
+ gem 'untied-consumer'
10
+
11
+ # Gems used only for assets and not required
12
+ # in production environments by default.
13
+ group :assets do
14
+ gem 'sass-rails', '~> 3.2.3'
15
+ gem 'coffee-rails', '~> 3.2.1'
16
+
17
+ # See https://github.com/sstephenson/execjs#readme for more supported runtimes
18
+ # gem 'therubyracer', :platforms => :ruby
19
+
20
+ gem 'uglifier', '>= 1.0.3'
21
+ end
22
+
23
+ gem 'jquery-rails'
24
+
25
+ # To use ActiveModel has_secure_password
26
+ # gem 'bcrypt-ruby', '~> 3.0.0'
27
+
28
+ # To use Jbuilder templates for JSON
29
+ # gem 'jbuilder'
30
+
31
+ # Use unicorn as the app server
32
+ # gem 'unicorn'
33
+
34
+ # Deploy with Capistrano
35
+ # gem 'capistrano'
36
+
37
+ # To use debugger
38
+ gem 'debugger'
@@ -0,0 +1,37 @@
1
+ # Untied::Consumer Rails example
2
+
3
+ This project shows how to use the [Untied](http://github.com/redu/untied) gem in a Rails project.
4
+
5
+ The untied Gem relies on RabbitMQ, so it need to be installed in order to work properly. [Here are](http://www.rabbitmq.com/download.html) the instructions.
6
+
7
+ ## Structure
8
+
9
+ The relevant files are:
10
+
11
+ ```
12
+ Gemfile
13
+ app/models/
14
+ ├── untied_user_observer.rb
15
+ └── user.rb
16
+ config/initializers/
17
+ └── untied.rb
18
+ ```
19
+
20
+ - The Gemfile adds untied-consumer as a dependency;
21
+ - The ``app/models/untied_user_observer.rb`` listens the Message Bus for User creation events. It inherits from Untied::Consumer::Observer and works in a similar way as the well known ActiveRecord::Observer;
22
+ - The ``config/initializes/untied.rb`` registers UntiedUserObserver;
23
+
24
+
25
+ ## Running the server
26
+
27
+ ```sh
28
+ $> bundle install
29
+ $> bundle exec rails s
30
+ ```
31
+
32
+ ## Starting the worker
33
+
34
+ ```sh
35
+ $> rabbitmq-server
36
+ $> rake untied:consumer:work
37
+ ```
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
3
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4
+
5
+ require File.expand_path('../config/application', __FILE__)
6
+
7
+ UntiedRailsExample::Application.load_tasks
@@ -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 .
@@ -0,0 +1,3 @@
1
+ # Place all the behaviors and hooks related to the matching controller here.
2
+ # All this logic will automatically be available in application.js.
3
+ # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */