url-agent 1.0.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.
- checksums.yaml +7 -0
- data/README.md +48 -0
- data/examples/config/urls.yaml +20 -0
- data/examples/google_evented.rb +20 -0
- data/examples/log/urls.log +635 -0
- data/lib/url-agent.rb +20 -0
- data/lib/url_agent/base.rb +144 -0
- data/lib/url_agent/dispatcher.rb +20 -0
- data/lib/url_agent/dispatcher/em_http.rb +44 -0
- data/lib/url_agent/exceptions.rb +23 -0
- data/lib/url_agent/logger.rb +11 -0
- data/lib/url_agent/pinger.rb +49 -0
- data/lib/url_agent/url.rb +60 -0
- data/lib/url_agent/url_set.rb +26 -0
- metadata +240 -0
data/lib/url-agent.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module URLAgent
|
5
|
+
class << self
|
6
|
+
attr_reader :root
|
7
|
+
attr_accessor :logger
|
8
|
+
|
9
|
+
def root=(path)
|
10
|
+
@root = Pathname.new("#{File.expand_path(path || Dir.pwd)}").realdirpath
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require_relative 'url_agent/logger'
|
16
|
+
require_relative 'url_agent/exceptions'
|
17
|
+
require_relative 'url_agent/url'
|
18
|
+
require_relative 'url_agent/url_set'
|
19
|
+
require_relative 'url_agent/base'
|
20
|
+
require_relative 'url_agent/pinger'
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'logger'
|
3
|
+
require 'yaml'
|
4
|
+
require 'uri'
|
5
|
+
require 'active_support/core_ext/hash'
|
6
|
+
|
7
|
+
require_relative 'dispatcher'
|
8
|
+
|
9
|
+
class URLAgent::Base
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
attr_reader :logger, :pinger
|
13
|
+
attr_accessor :urls
|
14
|
+
|
15
|
+
def initialize(options = {})
|
16
|
+
@configured = false
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
def configure(options = {})
|
21
|
+
return if configured?
|
22
|
+
configure!(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def configure!(options)
|
26
|
+
URLAgent.root = options[:path_root]
|
27
|
+
|
28
|
+
unless url_configuration_file.exist?
|
29
|
+
raise URLAgent::ConfigurationNotFoundException, "Cannot find #{url_configuration_file}"
|
30
|
+
end
|
31
|
+
|
32
|
+
@evented = begin
|
33
|
+
require_eventmachine_libraries
|
34
|
+
rescue LoadError
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
@urls ||= {}
|
39
|
+
|
40
|
+
url_configuration_load
|
41
|
+
initialize_logger
|
42
|
+
|
43
|
+
load_dispatcher
|
44
|
+
initialize_urls
|
45
|
+
configure_pinger
|
46
|
+
|
47
|
+
@configured = true
|
48
|
+
end
|
49
|
+
|
50
|
+
def configured?
|
51
|
+
@configured
|
52
|
+
end
|
53
|
+
|
54
|
+
def evented?
|
55
|
+
@evented
|
56
|
+
end
|
57
|
+
|
58
|
+
def [](identifier)
|
59
|
+
raise URLAgent::IdentifierNotFoundException unless @urls[identifier]
|
60
|
+
|
61
|
+
@urls[identifier].active
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def initialize_logger
|
67
|
+
return unless @options[:logger]
|
68
|
+
|
69
|
+
logger_file = URLAgent.root.join(@options[:logger][:path])
|
70
|
+
log_level = if @options[:verbose]
|
71
|
+
:DEBUG
|
72
|
+
else
|
73
|
+
@options[:logger][:log_level]
|
74
|
+
end.upcase.to_sym
|
75
|
+
|
76
|
+
raise URLAgent::LogDirectoryNotPresent unless logger_file.dirname.exist?
|
77
|
+
|
78
|
+
@logger = URLAgent::Logger.new(logger_file)
|
79
|
+
@logger.info "URL Agent starting up..."
|
80
|
+
@logger.info "Log level is #{log_level}"
|
81
|
+
@logger.level = ActiveSupport::Logger::Severity.const_get(log_level)
|
82
|
+
|
83
|
+
# Set this up as a logger available at the root
|
84
|
+
URLAgent.logger = @logger
|
85
|
+
end
|
86
|
+
|
87
|
+
def initialize_urls
|
88
|
+
@urls = Hash[@urls.map { |key, data| [key, URLAgent::UrlSet.new(data, :url_set_identifier => key, :dispatcher => @dispatcher)] }]
|
89
|
+
end
|
90
|
+
|
91
|
+
def url_configuration_file
|
92
|
+
URLAgent.root.join('config', 'urls.yaml')
|
93
|
+
end
|
94
|
+
|
95
|
+
def require_eventmachine_libraries
|
96
|
+
require 'em-http-request'
|
97
|
+
require 'em-synchrony'
|
98
|
+
require 'em-synchrony/em-http'
|
99
|
+
|
100
|
+
# We don't test for reactor_running? here, that's defered to the call method
|
101
|
+
true
|
102
|
+
end
|
103
|
+
|
104
|
+
def url_configuration_load
|
105
|
+
@urls = {}
|
106
|
+
url_configuration = File.open(url_configuration_file, 'r') { |f| YAML.load(f.read) }
|
107
|
+
url_configuration.symbolize_keys!
|
108
|
+
|
109
|
+
url_configuration.each do |identifier, data|
|
110
|
+
case identifier
|
111
|
+
when :logger
|
112
|
+
@options[:logger] = data.with_indifferent_access
|
113
|
+
when :pinger
|
114
|
+
@options[:pinger] = data.with_indifferent_access
|
115
|
+
when :timeouts
|
116
|
+
@options[:timeouts] = data.with_indifferent_access
|
117
|
+
else
|
118
|
+
@urls[identifier] = data
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def load_dispatcher
|
124
|
+
type = if evented?
|
125
|
+
:em_http
|
126
|
+
else
|
127
|
+
:net_http
|
128
|
+
end
|
129
|
+
|
130
|
+
logger.info "Using #{type} dispatcher"
|
131
|
+
|
132
|
+
@dispatcher = URLAgent::Dispatcher.new(@options.merge({ :type => type }))
|
133
|
+
end
|
134
|
+
|
135
|
+
def configure_pinger
|
136
|
+
return unless evented?
|
137
|
+
return unless @options[:pinger]
|
138
|
+
|
139
|
+
@pinger = URLAgent::Pinger.new(@urls, @options[:pinger])
|
140
|
+
|
141
|
+
logger.info "Pinger started"
|
142
|
+
@pinger.monitor
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class URLAgent::Dispatcher
|
2
|
+
attr_reader :proxy
|
3
|
+
|
4
|
+
def initialize(options = {})
|
5
|
+
type = options.delete(:type) || :net_http
|
6
|
+
@proxy = case type
|
7
|
+
when :net_http
|
8
|
+
require_relative 'dispatcher/net_http'
|
9
|
+
URLAgent::NetHTTPDispatcher.new(options)
|
10
|
+
when :em_http
|
11
|
+
require_relative 'dispatcher/em_http'
|
12
|
+
URLAgent::EMHTTPDispatcher.new(options)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute_request(http_verb, url_name, url, request_options = {})
|
17
|
+
@proxy.execute_request(http_verb, url_name, url, request_options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
class URLAgent::EMHTTPDispatcher
|
3
|
+
def initialize(url_agent_options)
|
4
|
+
@connection_options ||= {}
|
5
|
+
|
6
|
+
if url_agent_options[:timeouts]
|
7
|
+
@connection_options[:connect_timeout] = url_agent_options[:timeouts][:connection]
|
8
|
+
@connection_options[:inactivity_timeout] = url_agent_options[:timeouts][:inactivity]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute_request(http_verb, url_name, url, request_options = {})
|
13
|
+
check_for_eventmachine!
|
14
|
+
|
15
|
+
logger.debug "#{http_verb.upcase}\t#{url_name}\t#{url}\t#{request_options.inspect}"
|
16
|
+
|
17
|
+
request = EventMachine::HttpRequest.new(url, @connection_options).send(http_verb, request_options)
|
18
|
+
|
19
|
+
unless request.error.to_s.empty?
|
20
|
+
logger.error "#{http_verb.upcase}\t#{url_name}\t#{url}\t#{request_options.inspect}\tConnection Error"
|
21
|
+
raise URLAgent::ConnectionError, request.error
|
22
|
+
end
|
23
|
+
|
24
|
+
unless request.finished?
|
25
|
+
logger.error "#{http_verb.upcase}\t#{url_name}\t#{url}\t#{request_options.inspect}\tTimeout Exception"
|
26
|
+
raise URLAgent::TimeoutException
|
27
|
+
end
|
28
|
+
|
29
|
+
logger.debug "#{http_verb.upcase}-RESPONSE\t#{url_name}\t#{url}\t#{request_options.inspect}\t#{request.response.length}\t#{request.response.inspect[0..200]}"
|
30
|
+
|
31
|
+
request
|
32
|
+
end
|
33
|
+
|
34
|
+
def logger
|
35
|
+
URLAgent.logger
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def check_for_eventmachine!(&block)
|
40
|
+
unless EM.reactor_running?
|
41
|
+
raise URLAgent::EMHTTPDispatcherReactorNotRunning, "The reactor is not running. You should wrap calls to the EMHTTPDispatcher around a EM.synchrony block"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class URLAgent::ConfigurationNotFoundException < Exception
|
2
|
+
end
|
3
|
+
|
4
|
+
class URLAgent::GemsNotFoundException < Exception
|
5
|
+
end
|
6
|
+
|
7
|
+
class URLAgent::IdentifierNotFoundException < Exception
|
8
|
+
end
|
9
|
+
|
10
|
+
class URLAgent::TimeoutException < Exception
|
11
|
+
end
|
12
|
+
|
13
|
+
class URLAgent::ConnectionError < Exception
|
14
|
+
end
|
15
|
+
|
16
|
+
class URLAgent::NoLiveURLFound < Exception
|
17
|
+
end
|
18
|
+
|
19
|
+
class URLAgent::EMHTTPDispatcherReactorNotRunning < Exception
|
20
|
+
end
|
21
|
+
|
22
|
+
class URLAgent::LogDirectoryNotPresent < Exception
|
23
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'active_support/core_ext/date_time'
|
2
|
+
require 'active_support/logger'
|
3
|
+
|
4
|
+
class URLAgent::Logger < ActiveSupport::Logger
|
5
|
+
|
6
|
+
class ActiveSupport::Logger::SimpleFormatter
|
7
|
+
def call(severity, time, progname, msg)
|
8
|
+
msg = "#{Time.now.to_formatted_s(:db)}, #{severity} #{msg.strip}\n"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'active_support/core_ext/hash'
|
2
|
+
|
3
|
+
class URLAgent::Pinger
|
4
|
+
attr_accessor :url_sets, :pinger_configuration, :tick
|
5
|
+
|
6
|
+
def initialize(url_sets, pinger_configuration)
|
7
|
+
@url_sets = url_sets
|
8
|
+
@pinger_configuration = pinger_configuration
|
9
|
+
@tick = @pinger_configuration[:tick] || 10
|
10
|
+
end
|
11
|
+
|
12
|
+
def monitor
|
13
|
+
return unless EM.reactor_running?
|
14
|
+
|
15
|
+
logger.debug "MONITOR"
|
16
|
+
EM.add_periodic_timer(@tick) { Fiber.new { check }.resume }
|
17
|
+
end
|
18
|
+
|
19
|
+
def check
|
20
|
+
@url_sets.each do |url_set_identifier, set|
|
21
|
+
url_configuration = pinger_configuration[url_set_identifier]
|
22
|
+
url_parameters = url_configuration["params"].symbolize_keys
|
23
|
+
http_verb = (url_configuration['verb'] || "get").to_sym
|
24
|
+
|
25
|
+
set.urls.each do |url_identifier, url|
|
26
|
+
begin
|
27
|
+
url_built = url.build(url_parameters)
|
28
|
+
|
29
|
+
logger.debug "CHECK\t#{url_set_identifier}:#{url_identifier}\t#{url_built}"
|
30
|
+
connection = url_built.send(http_verb)
|
31
|
+
logger.debug "CHECK-RESPONSE\t#{url_set_identifier}:#{url_identifier}\t#{url_built}\t#{connection.response.length}\t#{connection.response.inspect[0..200]}"
|
32
|
+
|
33
|
+
logger.info "ALIVE\t#{url_set_identifier}:#{url_identifier}\t#{url_built}"
|
34
|
+
url.alive!
|
35
|
+
rescue URLAgent::ConnectionError
|
36
|
+
logger.warn "DEAD\t#{url_set_identifier}:#{url_identifier}\t#{url_built}\tConnection Error"
|
37
|
+
url.dead!
|
38
|
+
rescue URLAgent::TimeoutException
|
39
|
+
logger.warn "DEAD\t#{url_set_identifier}:#{url_identifier}\t#{url_built}\tTimeout Exception"
|
40
|
+
url.dead!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def logger
|
47
|
+
URLAgent.logger
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class URLAgent::Url
|
2
|
+
attr_accessor :live
|
3
|
+
|
4
|
+
def initialize(url, options = {})
|
5
|
+
@url = url
|
6
|
+
|
7
|
+
@dispatcher = options[:dispatcher]
|
8
|
+
@live = options[:live].nil? ? true : options[:live]
|
9
|
+
@url_set_identifier = options[:url_set_identifier]
|
10
|
+
@identifier = options[:identifier]
|
11
|
+
|
12
|
+
unless @dispatcher
|
13
|
+
raise ArgumentError, "Must provide a dispatcher to construct a callable URL."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def build(parameters = {})
|
18
|
+
url_with_parameters = @url.dup
|
19
|
+
parameters.each do |parameter_name, parameter_value|
|
20
|
+
url_with_parameters.gsub!("%%#{parameter_name}%%", URI.escape("#{parameter_value}"))
|
21
|
+
end
|
22
|
+
|
23
|
+
self.class.new(url_with_parameters, { :dispatcher => @dispatcher, :live => @live, :url_set_identifier => @url_set_identifier, :identifier => @identifier })
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
@url.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
[:get, :head, :post, :put].each do |http_verb|
|
31
|
+
self.class_eval do
|
32
|
+
define_method http_verb do |request_options = {}|
|
33
|
+
logger.debug "DISPATCH\t#{url_name}\t#{self.to_s}\t#{__method__.upcase}"
|
34
|
+
@dispatcher.execute_request(http_verb, url_name, self.to_s, request_options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
alias :call :get
|
40
|
+
|
41
|
+
def dead!
|
42
|
+
@live = false
|
43
|
+
end
|
44
|
+
|
45
|
+
def alive!
|
46
|
+
@live = true
|
47
|
+
end
|
48
|
+
|
49
|
+
def alive?
|
50
|
+
@live
|
51
|
+
end
|
52
|
+
|
53
|
+
def logger
|
54
|
+
URLAgent.logger
|
55
|
+
end
|
56
|
+
|
57
|
+
def url_name
|
58
|
+
"#{@url_set_identifier}:#{@identifier}"
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class URLAgent::UrlSet
|
2
|
+
attr_reader :urls
|
3
|
+
|
4
|
+
def initialize(urls, options = {})
|
5
|
+
@urls = {}
|
6
|
+
urls.each do |identifier, url|
|
7
|
+
@urls[identifier] = URLAgent::Url.new(url, options.merge(:identifier => identifier))
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def active
|
12
|
+
(@urls.select { |key, url| url.alive? }).values.first or raise URLAgent::NoLiveURLFound, "No active url found!"
|
13
|
+
end
|
14
|
+
|
15
|
+
def dead!(identifier)
|
16
|
+
@urls[identifier].dead!
|
17
|
+
end
|
18
|
+
|
19
|
+
def alive!(identifier)
|
20
|
+
@urls[identifier].alive!
|
21
|
+
end
|
22
|
+
|
23
|
+
def build(arguments = {})
|
24
|
+
active.build(arguments)
|
25
|
+
end
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: url-agent
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vishnu Gopal
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
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: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: guard-rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov-rcov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: flog
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: ci_reporter
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: eventmachine
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 1.0.0.beta
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 1.0.0.beta
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: em-http-request
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: em-synchrony
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: activesupport
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
description: URL agent can handle common errors, concurrency and fallback for applications
|
196
|
+
that call a large number of URLs.
|
197
|
+
email:
|
198
|
+
- vishnu@mobme.in
|
199
|
+
executables: []
|
200
|
+
extensions: []
|
201
|
+
extra_rdoc_files: []
|
202
|
+
files:
|
203
|
+
- README.md
|
204
|
+
- examples/config/urls.yaml
|
205
|
+
- examples/google_evented.rb
|
206
|
+
- examples/log/urls.log
|
207
|
+
- lib/url-agent.rb
|
208
|
+
- lib/url_agent/base.rb
|
209
|
+
- lib/url_agent/dispatcher.rb
|
210
|
+
- lib/url_agent/dispatcher/em_http.rb
|
211
|
+
- lib/url_agent/exceptions.rb
|
212
|
+
- lib/url_agent/logger.rb
|
213
|
+
- lib/url_agent/pinger.rb
|
214
|
+
- lib/url_agent/url.rb
|
215
|
+
- lib/url_agent/url_set.rb
|
216
|
+
homepage: http://www.mobme.in/
|
217
|
+
licenses: []
|
218
|
+
metadata: {}
|
219
|
+
post_install_message:
|
220
|
+
rdoc_options: []
|
221
|
+
require_paths:
|
222
|
+
- lib
|
223
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
224
|
+
requirements:
|
225
|
+
- - ">="
|
226
|
+
- !ruby/object:Gem::Version
|
227
|
+
version: '0'
|
228
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
229
|
+
requirements:
|
230
|
+
- - ">="
|
231
|
+
- !ruby/object:Gem::Version
|
232
|
+
version: 1.3.6
|
233
|
+
requirements: []
|
234
|
+
rubyforge_project:
|
235
|
+
rubygems_version: 2.2.2
|
236
|
+
signing_key:
|
237
|
+
specification_version: 4
|
238
|
+
summary: URL Agent acts as a proxy for managing URL access for applications
|
239
|
+
test_files: []
|
240
|
+
has_rdoc:
|