gongren-rails 0.1.1
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/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +66 -0
- data/Rakefile +109 -0
- data/VERSION +1 -0
- data/gongren-rails.gemspec +68 -0
- data/lib/gongren/call_proxy.rb +25 -0
- data/lib/gongren/rails.rb +6 -0
- data/lib/gongren/rails/extensions/action_mailer.rb +13 -0
- data/lib/gongren/rails/extensions/active_record.rb +28 -0
- data/lib/gongren/rails/server.rb +66 -0
- data/lib/gongren/rails/worker.rb +70 -0
- data/test/helper.rb +10 -0
- data/test/test_gongren-rails.rb +7 -0
- metadata +110 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 François Beausoleil
|
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.rdoc
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
= gongren-rails
|
2
|
+
|
3
|
+
gongren-rails is for use specifically within Rails. It includes extensions to ActiveRecord, ActionController
|
4
|
+
and ActionMailer to make queuing jobs for later easier.
|
5
|
+
|
6
|
+
== Basic Usage
|
7
|
+
|
8
|
+
# config/environment.rb
|
9
|
+
Rails::Initializer.run do |config|
|
10
|
+
# Will pull in all needed dependencies
|
11
|
+
config.gem "gongren-rails", :lib => "gongren/server"
|
12
|
+
|
13
|
+
config.after_initialize do
|
14
|
+
# Reads config/amqp.yml, or uses default configuration
|
15
|
+
Gongren::RailsServer.start
|
16
|
+
|
17
|
+
# OR, manual configuration
|
18
|
+
Gongren::Rails::Server.start(:host => "rabbit.myhost.com",
|
19
|
+
:port => 1234,
|
20
|
+
:user => "not-guest",
|
21
|
+
:password => "not-empty")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# ActiveRecord model, callback
|
26
|
+
class BlogComment < ActiveRecord::Base
|
27
|
+
def evaluate_for_spaminess
|
28
|
+
# Potentially hanging network call to Defensio or other.
|
29
|
+
end
|
30
|
+
|
31
|
+
# NOT IMPLEMENTED YET
|
32
|
+
# queued_after_create :evaluate_for_spaminess, :key => "comment.spam"
|
33
|
+
# queued_after_update :evaluate_for_spaminess, :key => "comment.spam"
|
34
|
+
# queued_after_save :evaluate_for_spaminess, :key => "comment.spam"
|
35
|
+
|
36
|
+
# Manually enqueue a method call
|
37
|
+
after_create do |comment|
|
38
|
+
comment.queue(:key => "comment.spam").evaluate_for_spaminess
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# ActionMailer helper
|
43
|
+
class UsersController < ActionController::Base
|
44
|
+
def create
|
45
|
+
user = User.create!(params[:user])
|
46
|
+
url = user_confirmation_url(:id => user.id, :token => user.confirmation_token)
|
47
|
+
UserMailer.queue(:key => "user.welcome").deliver_confirmation_email(:user => user, :url => url)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
The +key+ parameters above allows routing different jobs to different Gongren::Worker instances. See
|
52
|
+
the README documentation of the Gongren gem itself for details on usage and purpose.
|
53
|
+
|
54
|
+
== Note on Patches/Pull Requests
|
55
|
+
|
56
|
+
* Fork the project.
|
57
|
+
* Make your feature addition or bug fix.
|
58
|
+
* Add tests for it. This is important so I don't break it in a
|
59
|
+
future version unintentionally.
|
60
|
+
* Commit, do not mess with rakefile, version, or history.
|
61
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
62
|
+
* Send me a pull request. Bonus points for topic branches.
|
63
|
+
|
64
|
+
== Copyright
|
65
|
+
|
66
|
+
Copyright (c) 2010 François Beausoleil. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "gongren-rails"
|
8
|
+
gem.summary = %Q{Gongren::Server specifically for use within Rails.}
|
9
|
+
gem.description = %Q{Gongren::Rails::Server is what you're after.}
|
10
|
+
gem.email = "francois@teksol.info"
|
11
|
+
gem.homepage = "http://github.com/francois/gongren-rails"
|
12
|
+
gem.authors = ["François Beausoleil"]
|
13
|
+
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
14
|
+
gem.add_development_dependency "yard", ">= 0"
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
|
17
|
+
gem.add_dependency "gongren", ">= 0.1.2"
|
18
|
+
gem.add_dependency "qusion", ">= 1.0.0"
|
19
|
+
end
|
20
|
+
Jeweler::GemcutterTasks.new
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'rake/testtask'
|
26
|
+
Rake::TestTask.new(:test) do |test|
|
27
|
+
test.libs << 'lib' << 'test'
|
28
|
+
test.pattern = 'test/**/test_*.rb'
|
29
|
+
test.verbose = true
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
require 'rcov/rcovtask'
|
34
|
+
Rcov::RcovTask.new do |test|
|
35
|
+
test.libs << 'test'
|
36
|
+
test.pattern = 'test/**/test_*.rb'
|
37
|
+
test.verbose = true
|
38
|
+
end
|
39
|
+
rescue LoadError
|
40
|
+
task :rcov do
|
41
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
task :test => :check_dependencies
|
46
|
+
|
47
|
+
begin
|
48
|
+
require 'reek/adapters/rake_task'
|
49
|
+
Reek::RakeTask.new do |t|
|
50
|
+
t.fail_on_error = true
|
51
|
+
t.verbose = false
|
52
|
+
t.source_files = 'lib/**/*.rb'
|
53
|
+
end
|
54
|
+
rescue LoadError
|
55
|
+
task :reek do
|
56
|
+
abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
begin
|
61
|
+
require 'roodi'
|
62
|
+
require 'roodi_task'
|
63
|
+
RoodiTask.new do |t|
|
64
|
+
t.verbose = false
|
65
|
+
end
|
66
|
+
rescue LoadError
|
67
|
+
task :roodi do
|
68
|
+
abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
task :default => :test
|
73
|
+
|
74
|
+
begin
|
75
|
+
require 'yard'
|
76
|
+
YARD::Rake::YardocTask.new
|
77
|
+
rescue LoadError
|
78
|
+
task :yardoc do
|
79
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
namespace :version do
|
84
|
+
task :rewrite do
|
85
|
+
require "erb"
|
86
|
+
|
87
|
+
version = File.read("VERSION").chomp
|
88
|
+
template = ERB.new <<-EOT.gsub(/^\s{6}/, "")
|
89
|
+
# Nothing interesting here: see {Gongren::Rails::Server} or {Gongren::Rails::Worker}.
|
90
|
+
module Gongren
|
91
|
+
module Rails
|
92
|
+
VERSION = "<%= version %>"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
EOT
|
96
|
+
path = File.join(Dir.pwd, "lib/gongren/rails.rb")
|
97
|
+
contents = template.result(binding)
|
98
|
+
File.open(path, "w") {|out| out.write contents}
|
99
|
+
sha = `git log -n 1 --pretty=format:%H`.chomp
|
100
|
+
raise "Could not determine last commit" if sha.empty?
|
101
|
+
sh "git commit --amend --reuse-message #{sha} -- #{path}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
%w(version:bump:patch version:bump:minor version:bump:major).each do |name|
|
106
|
+
Rake::Task[name].enhance do
|
107
|
+
Rake::Task["version:rewrite"].invoke
|
108
|
+
end
|
109
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{gongren-rails}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Fran\303\247ois Beausoleil"]
|
12
|
+
s.date = %q{2010-01-20}
|
13
|
+
s.description = %q{Gongren::Rails::Server is what you're after.}
|
14
|
+
s.email = %q{francois@teksol.info}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"gongren-rails.gemspec",
|
27
|
+
"lib/gongren/call_proxy.rb",
|
28
|
+
"lib/gongren/rails.rb",
|
29
|
+
"lib/gongren/rails/extensions/action_mailer.rb",
|
30
|
+
"lib/gongren/rails/extensions/active_record.rb",
|
31
|
+
"lib/gongren/rails/server.rb",
|
32
|
+
"lib/gongren/rails/worker.rb",
|
33
|
+
"test/helper.rb",
|
34
|
+
"test/test_gongren-rails.rb"
|
35
|
+
]
|
36
|
+
s.homepage = %q{http://github.com/francois/gongren-rails}
|
37
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
38
|
+
s.require_paths = ["lib"]
|
39
|
+
s.rubygems_version = %q{1.3.5}
|
40
|
+
s.summary = %q{Gongren::Server specifically for use within Rails.}
|
41
|
+
s.test_files = [
|
42
|
+
"test/helper.rb",
|
43
|
+
"test/test_gongren-rails.rb"
|
44
|
+
]
|
45
|
+
|
46
|
+
if s.respond_to? :specification_version then
|
47
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
48
|
+
s.specification_version = 3
|
49
|
+
|
50
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
51
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
52
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
53
|
+
s.add_runtime_dependency(%q<gongren>, [">= 0.1.2"])
|
54
|
+
s.add_runtime_dependency(%q<qusion>, [">= 1.0.0"])
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
57
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
58
|
+
s.add_dependency(%q<gongren>, [">= 0.1.2"])
|
59
|
+
s.add_dependency(%q<qusion>, [">= 1.0.0"])
|
60
|
+
end
|
61
|
+
else
|
62
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
63
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
64
|
+
s.add_dependency(%q<gongren>, [">= 0.1.2"])
|
65
|
+
s.add_dependency(%q<qusion>, [">= 1.0.0"])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Gongren
|
2
|
+
class CallProxy
|
3
|
+
def initialize(options={}, &block)
|
4
|
+
@options = options
|
5
|
+
@block = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(selector, *args, &block)
|
9
|
+
raise ArgumentError, "Cannot generate a CallProxy when a block is involved" if block.present?
|
10
|
+
return super unless selector.to_s =~ /^deliver_/
|
11
|
+
data = {:selector => selector, :args => args}
|
12
|
+
@block.call(data) if @block
|
13
|
+
|
14
|
+
args = map_active_record_instances_to_simpler_representation(args)
|
15
|
+
|
16
|
+
Gongren::RailsServer.submit(options[:key], data)
|
17
|
+
end
|
18
|
+
|
19
|
+
def map_active_record_instances_to_simpler_representation(args)
|
20
|
+
args.map do |arg|
|
21
|
+
arg.kind_of?(ActiveRecord) ? {:active_record => [arg.class.name, arg.id]} : arg
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Gongren
|
2
|
+
module Rails
|
3
|
+
module Extensions
|
4
|
+
module ActiveRecord
|
5
|
+
# TODO: Map from *args to a block / #call-able something
|
6
|
+
def self.queued_after_save(*args, &block)
|
7
|
+
raise "not implemented"
|
8
|
+
end
|
9
|
+
|
10
|
+
# TODO: Map from *args to a block / #call-able something
|
11
|
+
def self.queued_after_update(*args, &block)
|
12
|
+
raise "not implemented"
|
13
|
+
end
|
14
|
+
|
15
|
+
# TODO: Map from *args to a block / #call-able something
|
16
|
+
def self.queued_after_create(*args, &block)
|
17
|
+
raise "not implemented"
|
18
|
+
end
|
19
|
+
|
20
|
+
def queue(options)
|
21
|
+
CallProxy.new(options) do |data|
|
22
|
+
data[:receiver] = {:active_record => [self.class.name, self.id]}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require "logger"
|
2
|
+
require "qusion"
|
3
|
+
|
4
|
+
require "gongren/rails/extensions/active_record" if defined?(ActiveRecord::Base)
|
5
|
+
require "gongren/rails/extensions/action_mailer" if defined?(ActionMailer::Base)
|
6
|
+
|
7
|
+
module Gongren
|
8
|
+
module Rails
|
9
|
+
class Server
|
10
|
+
def initialize(options={})
|
11
|
+
@options = options.symbolize_keys
|
12
|
+
@logger = options[:logger] || Rails.logger
|
13
|
+
end
|
14
|
+
|
15
|
+
# Submits a unit of work to the pool of workers.
|
16
|
+
def self.submit(name, unit)
|
17
|
+
data = Marshal.dump(unit)
|
18
|
+
|
19
|
+
# NOTE: mandatory => true means return an error if the message can't be routed immediately.
|
20
|
+
# This would indicate a configuration error, as workers should build their queue and
|
21
|
+
# bind them to the exchange on startup.
|
22
|
+
topic.publish(data, :persistent => true, :mandatory => true, :routing_key => "unit.#{name}")
|
23
|
+
end
|
24
|
+
|
25
|
+
# A quick way to instantiate a server with some options.
|
26
|
+
def self.start(options={})
|
27
|
+
new(options).start
|
28
|
+
end
|
29
|
+
|
30
|
+
# Starts the reactor / event loop.
|
31
|
+
def start
|
32
|
+
logger.info { "Gongren::Server #{Process.pid} starting" }
|
33
|
+
Qusion.start(@options)
|
34
|
+
self.class.control_topic # Instantiates the control topic, for later use
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :options, :logger
|
40
|
+
|
41
|
+
def self.exchange_name
|
42
|
+
"gongren.work"
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.exchange_options
|
46
|
+
{:durable => true}
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.topic
|
50
|
+
Qusion.channel.topic(exchange_name, exchange_options)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.control_exchange_name
|
54
|
+
"gongren.worker.control"
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.control_exchange_options
|
58
|
+
{}
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.control_topic
|
62
|
+
Qusion.channel.topic(control_exchange_name, control_exchange_options)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Gongren
|
2
|
+
module Rails
|
3
|
+
class Worker < Gongren::Worker
|
4
|
+
def start
|
5
|
+
raise ArgumentError, "#start must be called with a block" unless block_given?
|
6
|
+
|
7
|
+
logger.info { "Gongren::RailsWorker #{worker_id} ready to work" }
|
8
|
+
|
9
|
+
AMQP.start do
|
10
|
+
MQ.queue(control_queue_name, control_queue_options).bind(control_exchange_name, control_exchange_options) do |header, data|
|
11
|
+
message = Marshal.load(data)
|
12
|
+
logger.info { message.inspect }
|
13
|
+
|
14
|
+
if message[:selector].to_s.strip.empty? then
|
15
|
+
logger.error { "Received control request without :selector key: ignoring" }
|
16
|
+
else
|
17
|
+
begin
|
18
|
+
send(message[:selector], message)
|
19
|
+
rescue Exception => e
|
20
|
+
log_failure(header, message, e)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
MQ.queue(queue_name, queue_options).bind(exchange_name, exchange_options).subscribe(:ack => true) do |header, data|
|
26
|
+
message = Marshal.load(data)
|
27
|
+
class << message; include Unit; end # Dynamically add our #ack method
|
28
|
+
message.gongren_header = header
|
29
|
+
|
30
|
+
logger.info { message.inspect }
|
31
|
+
receiver = case keys = message[:receiver].keys
|
32
|
+
when [:active_record]
|
33
|
+
active_record_model(message[:receiver][:active_record])
|
34
|
+
when [:class]
|
35
|
+
message[:receiver][:class].constantize
|
36
|
+
else
|
37
|
+
raise UnknownReceiverKeys, "Unable to map from #{keys} to a receiver instance: aborting"
|
38
|
+
end
|
39
|
+
message.args.collect! do |arg|
|
40
|
+
if arg.kind_of?(Hash) && arg[:active_record] then
|
41
|
+
active_record_model(arg[:active_record])
|
42
|
+
else
|
43
|
+
arg
|
44
|
+
end
|
45
|
+
end
|
46
|
+
logger.debug { "Mapped message is:\n#{message.inspect}" }
|
47
|
+
|
48
|
+
begin
|
49
|
+
receiver.send(message[:selector], *message[:args])
|
50
|
+
|
51
|
+
# Automatically ack messages, but do it only once
|
52
|
+
logger.debug { "Block ack'd? #{message.acked?}" }
|
53
|
+
unless message.acked?
|
54
|
+
logger.debug { "Ack'ing for the block" }
|
55
|
+
message.ack
|
56
|
+
end
|
57
|
+
rescue Exception => e
|
58
|
+
log_failure(header, message, e)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Given a two element Array of ["ClassName", ID], returns an ActiveRecord instance.
|
65
|
+
def active_record_model(ar)
|
66
|
+
ar.first.constantize.find(ar.last)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/test/helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gongren-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "Fran\xC3\xA7ois Beausoleil"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-20 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thoughtbot-shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: yard
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: gongren
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.1.2
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: qusion
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.0.0
|
54
|
+
version:
|
55
|
+
description: Gongren::Rails::Server is what you're after.
|
56
|
+
email: francois@teksol.info
|
57
|
+
executables: []
|
58
|
+
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- LICENSE
|
63
|
+
- README.rdoc
|
64
|
+
files:
|
65
|
+
- .document
|
66
|
+
- .gitignore
|
67
|
+
- LICENSE
|
68
|
+
- README.rdoc
|
69
|
+
- Rakefile
|
70
|
+
- VERSION
|
71
|
+
- gongren-rails.gemspec
|
72
|
+
- lib/gongren/call_proxy.rb
|
73
|
+
- lib/gongren/rails.rb
|
74
|
+
- lib/gongren/rails/extensions/action_mailer.rb
|
75
|
+
- lib/gongren/rails/extensions/active_record.rb
|
76
|
+
- lib/gongren/rails/server.rb
|
77
|
+
- lib/gongren/rails/worker.rb
|
78
|
+
- test/helper.rb
|
79
|
+
- test/test_gongren-rails.rb
|
80
|
+
has_rdoc: true
|
81
|
+
homepage: http://github.com/francois/gongren-rails
|
82
|
+
licenses: []
|
83
|
+
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options:
|
86
|
+
- --charset=UTF-8
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: "0"
|
94
|
+
version:
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: "0"
|
100
|
+
version:
|
101
|
+
requirements: []
|
102
|
+
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.3.5
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: Gongren::Server specifically for use within Rails.
|
108
|
+
test_files:
|
109
|
+
- test/helper.rb
|
110
|
+
- test/test_gongren-rails.rb
|