wayfarer-jruby 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rbenv-gemsets +1 -0
- data/.rspec +3 -0
- data/.rubocop.yml +21 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/.yardopts +3 -0
- data/Gemfile +11 -0
- data/LICENSE +19 -0
- data/README.md +19 -0
- data/Rakefile +114 -0
- data/benchmark/frontiers.rb +143 -0
- data/bin/wayfarer +116 -0
- data/docs/.gitignore +2 -0
- data/docs/_config.yml +15 -0
- data/docs/_includes/base.html +7 -0
- data/docs/_includes/head.html +10 -0
- data/docs/_includes/navigation.html +172 -0
- data/docs/_layouts/default.html +42 -0
- data/docs/_sass/base.scss +439 -0
- data/docs/_sass/variables.scss +24 -0
- data/docs/_sass/vendor/bourbon/_bourbon-deprecate.scss +19 -0
- data/docs/_sass/vendor/bourbon/_bourbon-deprecated-upcoming.scss +425 -0
- data/docs/_sass/vendor/bourbon/_bourbon.scss +90 -0
- data/docs/_sass/vendor/bourbon/addons/_border-color.scss +29 -0
- data/docs/_sass/vendor/bourbon/addons/_border-radius.scss +48 -0
- data/docs/_sass/vendor/bourbon/addons/_border-style.scss +28 -0
- data/docs/_sass/vendor/bourbon/addons/_border-width.scss +28 -0
- data/docs/_sass/vendor/bourbon/addons/_buttons.scss +69 -0
- data/docs/_sass/vendor/bourbon/addons/_clearfix.scss +25 -0
- data/docs/_sass/vendor/bourbon/addons/_ellipsis.scss +30 -0
- data/docs/_sass/vendor/bourbon/addons/_font-stacks.scss +31 -0
- data/docs/_sass/vendor/bourbon/addons/_hide-text.scss +27 -0
- data/docs/_sass/vendor/bourbon/addons/_margin.scss +29 -0
- data/docs/_sass/vendor/bourbon/addons/_padding.scss +29 -0
- data/docs/_sass/vendor/bourbon/addons/_position.scss +51 -0
- data/docs/_sass/vendor/bourbon/addons/_prefixer.scss +66 -0
- data/docs/_sass/vendor/bourbon/addons/_retina-image.scss +27 -0
- data/docs/_sass/vendor/bourbon/addons/_size.scss +56 -0
- data/docs/_sass/vendor/bourbon/addons/_text-inputs.scss +118 -0
- data/docs/_sass/vendor/bourbon/addons/_timing-functions.scss +34 -0
- data/docs/_sass/vendor/bourbon/addons/_triangle.scss +63 -0
- data/docs/_sass/vendor/bourbon/addons/_word-wrap.scss +29 -0
- data/docs/_sass/vendor/bourbon/css3/_animation.scss +61 -0
- data/docs/_sass/vendor/bourbon/css3/_appearance.scss +5 -0
- data/docs/_sass/vendor/bourbon/css3/_backface-visibility.scss +5 -0
- data/docs/_sass/vendor/bourbon/css3/_background-image.scss +44 -0
- data/docs/_sass/vendor/bourbon/css3/_background.scss +57 -0
- data/docs/_sass/vendor/bourbon/css3/_border-image.scss +61 -0
- data/docs/_sass/vendor/bourbon/css3/_calc.scss +6 -0
- data/docs/_sass/vendor/bourbon/css3/_columns.scss +67 -0
- data/docs/_sass/vendor/bourbon/css3/_filter.scss +6 -0
- data/docs/_sass/vendor/bourbon/css3/_flex-box.scss +327 -0
- data/docs/_sass/vendor/bourbon/css3/_font-face.scss +29 -0
- data/docs/_sass/vendor/bourbon/css3/_font-feature-settings.scss +6 -0
- data/docs/_sass/vendor/bourbon/css3/_hidpi-media-query.scss +12 -0
- data/docs/_sass/vendor/bourbon/css3/_hyphens.scss +6 -0
- data/docs/_sass/vendor/bourbon/css3/_image-rendering.scss +15 -0
- data/docs/_sass/vendor/bourbon/css3/_keyframes.scss +38 -0
- data/docs/_sass/vendor/bourbon/css3/_linear-gradient.scss +40 -0
- data/docs/_sass/vendor/bourbon/css3/_perspective.scss +12 -0
- data/docs/_sass/vendor/bourbon/css3/_placeholder.scss +10 -0
- data/docs/_sass/vendor/bourbon/css3/_radial-gradient.scss +40 -0
- data/docs/_sass/vendor/bourbon/css3/_selection.scss +44 -0
- data/docs/_sass/vendor/bourbon/css3/_text-decoration.scss +27 -0
- data/docs/_sass/vendor/bourbon/css3/_transform.scss +21 -0
- data/docs/_sass/vendor/bourbon/css3/_transition.scss +81 -0
- data/docs/_sass/vendor/bourbon/css3/_user-select.scss +5 -0
- data/docs/_sass/vendor/bourbon/functions/_assign-inputs.scss +16 -0
- data/docs/_sass/vendor/bourbon/functions/_contains-falsy.scss +25 -0
- data/docs/_sass/vendor/bourbon/functions/_contains.scss +31 -0
- data/docs/_sass/vendor/bourbon/functions/_is-length.scss +16 -0
- data/docs/_sass/vendor/bourbon/functions/_is-light.scss +26 -0
- data/docs/_sass/vendor/bourbon/functions/_is-number.scss +16 -0
- data/docs/_sass/vendor/bourbon/functions/_is-size.scss +23 -0
- data/docs/_sass/vendor/bourbon/functions/_modular-scale.scss +74 -0
- data/docs/_sass/vendor/bourbon/functions/_px-to-em.scss +24 -0
- data/docs/_sass/vendor/bourbon/functions/_px-to-rem.scss +26 -0
- data/docs/_sass/vendor/bourbon/functions/_shade.scss +24 -0
- data/docs/_sass/vendor/bourbon/functions/_strip-units.scss +22 -0
- data/docs/_sass/vendor/bourbon/functions/_tint.scss +24 -0
- data/docs/_sass/vendor/bourbon/functions/_transition-property-name.scss +37 -0
- data/docs/_sass/vendor/bourbon/functions/_unpack.scss +32 -0
- data/docs/_sass/vendor/bourbon/helpers/_convert-units.scss +26 -0
- data/docs/_sass/vendor/bourbon/helpers/_directional-values.scss +108 -0
- data/docs/_sass/vendor/bourbon/helpers/_font-source-declaration.scss +53 -0
- data/docs/_sass/vendor/bourbon/helpers/_gradient-positions-parser.scss +24 -0
- data/docs/_sass/vendor/bourbon/helpers/_linear-angle-parser.scss +35 -0
- data/docs/_sass/vendor/bourbon/helpers/_linear-gradient-parser.scss +51 -0
- data/docs/_sass/vendor/bourbon/helpers/_linear-positions-parser.scss +77 -0
- data/docs/_sass/vendor/bourbon/helpers/_linear-side-corner-parser.scss +41 -0
- data/docs/_sass/vendor/bourbon/helpers/_radial-arg-parser.scss +74 -0
- data/docs/_sass/vendor/bourbon/helpers/_radial-gradient-parser.scss +55 -0
- data/docs/_sass/vendor/bourbon/helpers/_radial-positions-parser.scss +28 -0
- data/docs/_sass/vendor/bourbon/helpers/_render-gradients.scss +31 -0
- data/docs/_sass/vendor/bourbon/helpers/_shape-size-stripper.scss +15 -0
- data/docs/_sass/vendor/bourbon/helpers/_str-to-num.scss +55 -0
- data/docs/_sass/vendor/bourbon/settings/_asset-pipeline.scss +7 -0
- data/docs/_sass/vendor/bourbon/settings/_deprecation-warnings.scss +8 -0
- data/docs/_sass/vendor/bourbon/settings/_prefixer.scss +9 -0
- data/docs/_sass/vendor/bourbon/settings/_px-to-em.scss +1 -0
- data/docs/_sass/vendor/neat/_neat-helpers.scss +11 -0
- data/docs/_sass/vendor/neat/_neat.scss +23 -0
- data/docs/_sass/vendor/neat/functions/_new-breakpoint.scss +49 -0
- data/docs/_sass/vendor/neat/functions/_private.scss +114 -0
- data/docs/_sass/vendor/neat/grid/_box-sizing.scss +15 -0
- data/docs/_sass/vendor/neat/grid/_direction-context.scss +33 -0
- data/docs/_sass/vendor/neat/grid/_display-context.scss +28 -0
- data/docs/_sass/vendor/neat/grid/_fill-parent.scss +22 -0
- data/docs/_sass/vendor/neat/grid/_media.scss +92 -0
- data/docs/_sass/vendor/neat/grid/_omega.scss +87 -0
- data/docs/_sass/vendor/neat/grid/_outer-container.scss +34 -0
- data/docs/_sass/vendor/neat/grid/_pad.scss +25 -0
- data/docs/_sass/vendor/neat/grid/_private.scss +35 -0
- data/docs/_sass/vendor/neat/grid/_row.scss +52 -0
- data/docs/_sass/vendor/neat/grid/_shift.scss +50 -0
- data/docs/_sass/vendor/neat/grid/_span-columns.scss +94 -0
- data/docs/_sass/vendor/neat/grid/_to-deprecate.scss +97 -0
- data/docs/_sass/vendor/neat/grid/_visual-grid.scss +42 -0
- data/docs/_sass/vendor/neat/mixins/_clearfix.scss +25 -0
- data/docs/_sass/vendor/neat/settings/_disable-warnings.scss +13 -0
- data/docs/_sass/vendor/neat/settings/_grid.scss +51 -0
- data/docs/_sass/vendor/neat/settings/_visual-grid.scss +27 -0
- data/docs/_sass/vendor/normalize-3.0.2.scss +427 -0
- data/docs/_sass/vendor/pygments.scss +356 -0
- data/docs/automating_browsers/capybara.md +70 -0
- data/docs/css/screen.scss +7 -0
- data/docs/guides/callbacks.md +45 -0
- data/docs/guides/cli.md +52 -0
- data/docs/guides/configuration.md +184 -0
- data/docs/guides/error_handling.md +46 -0
- data/docs/guides/frontiers.md +93 -0
- data/docs/guides/halting.md +23 -0
- data/docs/guides/job_queues.md +26 -0
- data/docs/guides/locals.md +36 -0
- data/docs/guides/logging.md +22 -0
- data/docs/guides/page_objects.md +67 -0
- data/docs/guides/peeking.md +46 -0
- data/docs/guides/selenium_capybara.md +100 -0
- data/docs/guides/tutorial.md +452 -0
- data/docs/index.md +82 -0
- data/docs/js/navigation.js +11 -0
- data/docs/misc/contributing.md +20 -0
- data/docs/misc/testing.md +11 -0
- data/docs/recipes/authentication.md +23 -0
- data/docs/recipes/csv.md +29 -0
- data/docs/recipes/javascript.md +20 -0
- data/docs/recipes/multiple_uris.md +18 -0
- data/docs/recipes/screenshots.md +20 -0
- data/docs/routing/host_rules.md +24 -0
- data/docs/routing/path_rules.md +33 -0
- data/docs/routing/query_rules.md +69 -0
- data/docs/routing/routes.md +96 -0
- data/docs/routing/uri_rules.md +18 -0
- data/examples/collect_github_issues.rb +65 -0
- data/examples/find_foobar_on_wikipedia.rb +23 -0
- data/lib/wayfarer.rb +65 -0
- data/lib/wayfarer/configuration.rb +86 -0
- data/lib/wayfarer/crawl.rb +79 -0
- data/lib/wayfarer/crawl_observer.rb +103 -0
- data/lib/wayfarer/dispatcher.rb +104 -0
- data/lib/wayfarer/finders.rb +61 -0
- data/lib/wayfarer/frontiers/frontier.rb +79 -0
- data/lib/wayfarer/frontiers/memory_bloomfilter.rb +32 -0
- data/lib/wayfarer/frontiers/memory_frontier.rb +76 -0
- data/lib/wayfarer/frontiers/memory_trie_frontier.rb +39 -0
- data/lib/wayfarer/frontiers/normalize_uris.rb +48 -0
- data/lib/wayfarer/frontiers/redis_bloomfilter.rb +34 -0
- data/lib/wayfarer/frontiers/redis_frontier.rb +83 -0
- data/lib/wayfarer/http_adapters/adapter_pool.rb +62 -0
- data/lib/wayfarer/http_adapters/net_http_adapter.rb +77 -0
- data/lib/wayfarer/http_adapters/selenium_adapter.rb +80 -0
- data/lib/wayfarer/job.rb +192 -0
- data/lib/wayfarer/locals.rb +40 -0
- data/lib/wayfarer/page.rb +94 -0
- data/lib/wayfarer/parsers/json_parser.rb +20 -0
- data/lib/wayfarer/parsers/xml_parser.rb +27 -0
- data/lib/wayfarer/processor.rb +103 -0
- data/lib/wayfarer/routing/host_rule.rb +19 -0
- data/lib/wayfarer/routing/path_rule.rb +54 -0
- data/lib/wayfarer/routing/query_rule.rb +59 -0
- data/lib/wayfarer/routing/router.rb +71 -0
- data/lib/wayfarer/routing/rule.rb +102 -0
- data/lib/wayfarer/routing/uri_rule.rb +21 -0
- data/spec/configuration_spec.rb +26 -0
- data/spec/crawl_spec.rb +48 -0
- data/spec/finders_spec.rb +49 -0
- data/spec/frontiers/memory_bloomfilter_spec.rb +6 -0
- data/spec/frontiers/memory_frontier_spec.rb +6 -0
- data/spec/frontiers/memory_trie_frontier_spec.rb +6 -0
- data/spec/frontiers/normalize_uris_spec.rb +59 -0
- data/spec/frontiers/redis_bloomfilter_spec.rb +6 -0
- data/spec/frontiers/redis_frontier_spec.rb +6 -0
- data/spec/http_adapters/adapter_pool_spec.rb +33 -0
- data/spec/http_adapters/net_http_adapter_spec.rb +83 -0
- data/spec/http_adapters/selenium_adapter_spec.rb +53 -0
- data/spec/integration/callbacks_spec.rb +42 -0
- data/spec/integration/locals_spec.rb +106 -0
- data/spec/job_spec.rb +86 -0
- data/spec/page_spec.rb +38 -0
- data/spec/parsers/json_parser_spec.rb +30 -0
- data/spec/parsers/xml_parser_spec.rb +24 -0
- data/spec/processor_spec.rb +31 -0
- data/spec/routing/host_rule_spec.rb +48 -0
- data/spec/routing/path_rule_spec.rb +66 -0
- data/spec/routing/query_rule_spec.rb +124 -0
- data/spec/routing/router_spec.rb +67 -0
- data/spec/routing/rule_spec.rb +218 -0
- data/spec/routing/uri_rule_spec.rb +24 -0
- data/spec/shared/frontier.rb +96 -0
- data/spec/spec_helpers.rb +62 -0
- data/spec/wayfarer_spec.rb +24 -0
- data/support/static/finders.html +38 -0
- data/support/static/graph/details/a.html +10 -0
- data/support/static/graph/details/b.html +10 -0
- data/support/static/graph/index.html +20 -0
- data/support/static/json/dummy.json +13 -0
- data/support/static/links/links.html +28 -0
- data/support/static/xml/dummy.xml +120 -0
- data/support/test_app.rb +45 -0
- data/wayfarer-jruby.gemspec +49 -0
- data/wayfarer.gemspec +53 -0
- metadata +616 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 72b70dc0921adae626373012636e5646abae4586
|
4
|
+
data.tar.gz: 480b0c60cd58062d700de8a8f480386ba57f6dc7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 523c57e24ff35bf95f3ef49b4c2d0e169eef5d237ee3614593217e5f9d51721e67fb326a87fb86fd9b075b3aa938e78ff96a04d6e5589f92a8b6de969addab43
|
7
|
+
data.tar.gz: 6b686f439ea1ca38304150ee0f1a3d927bb7a36d6a87de580e273f608127ebde01b152cca3fc69cb8b78ef2082e7d3efb9edddd5b1f889ee07547ed4649a1e61
|
data/.gitignore
ADDED
data/.rbenv-gemsets
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
wayfarer
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- "spec/**/*"
|
4
|
+
- "examples/**/*"
|
5
|
+
- "support/**/*"
|
6
|
+
- "wayfarer.gemspec"
|
7
|
+
- "examples"
|
8
|
+
|
9
|
+
Style/StringLiterals:
|
10
|
+
EnforcedStyle: double_quotes
|
11
|
+
|
12
|
+
Style/BlockDelimiters:
|
13
|
+
EnforcedStyle: semantic
|
14
|
+
FunctionalMethods:
|
15
|
+
- expect
|
16
|
+
|
17
|
+
Metrics/MethodLength:
|
18
|
+
Max: 25
|
19
|
+
|
20
|
+
Metrics/PerceivedComplexity:
|
21
|
+
Max: 10
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.1
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2017 Dominic Bauer
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Wayfarer
|
2
|
+
[](https://travis-ci.org/bauerd/wayfarer)
|
3
|
+
[](https://codeclimate.com/github/bauerd/wayfarer)
|
4
|
+
|
5
|
+
Versatile web crawling with (J)Ruby
|
6
|
+
|
7
|
+
* [__Usage and more__ on the website](https://bauerd.github.io/wayfarer/)
|
8
|
+
* [__API documentation__ on Ruby-Doc.org](http://www.rubydoc.info/github/bauerd/wayfarer) (`master` branch)
|
9
|
+
* [__Releases__ on RubyGems.org](https://rubygems.org/gems/wayfarer)
|
10
|
+
|
11
|
+
MRI:
|
12
|
+
```
|
13
|
+
% [sudo] gem install wayfarer
|
14
|
+
```
|
15
|
+
|
16
|
+
JRuby:
|
17
|
+
```
|
18
|
+
% [sudo] gem install wayfarer-jruby
|
19
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rspec/core/rake_task"
|
4
|
+
require "rubocop/rake_task"
|
5
|
+
require "rack"
|
6
|
+
|
7
|
+
require_relative "support/test_app"
|
8
|
+
|
9
|
+
task default: ["ci"]
|
10
|
+
|
11
|
+
namespace :test do
|
12
|
+
desc "Run only environment-agnostic tests"
|
13
|
+
RSpec::Core::RakeTask.new isolated: [:test_app] do |task|
|
14
|
+
task.rspec_opts = ["--tag ~selenium --tag ~redis"]
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Run only integration tests"
|
18
|
+
RSpec::Core::RakeTask.new integration: [:test_app] do |task|
|
19
|
+
task.rspec_opts = ["--tag integration"]
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Run only Selenium tests"
|
23
|
+
RSpec::Core::RakeTask.new selenium: [:test_app] do |task|
|
24
|
+
task.rspec_opts = ["--tag selenium"]
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Run only Redis tests"
|
28
|
+
RSpec::Core::RakeTask.new redis: [:test_app] do |task|
|
29
|
+
task.rspec_opts = ["--tag redis"]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Run all tests"
|
34
|
+
RSpec::Core::RakeTask.new(test: :test_app)
|
35
|
+
|
36
|
+
RuboCop::RakeTask.new do |task|
|
37
|
+
task.formatters = ["simple"]
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "Run benchmarks"
|
41
|
+
task :benchmark do
|
42
|
+
bms = Rake::FileList["benchmark/*.rb"]
|
43
|
+
|
44
|
+
bms.each do |bm|
|
45
|
+
sh "bundle exec ruby #{bm}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "CI run"
|
50
|
+
task ci: %i[test benchmark]
|
51
|
+
|
52
|
+
namespace :build do
|
53
|
+
desc "Build the MRI gem"
|
54
|
+
task :mri do
|
55
|
+
sh "gem build wayfarer.gemspec --verbose"
|
56
|
+
sh "mkdir -p build"
|
57
|
+
sh "mv wayfarer-*.gem build"
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Build the MRI gem"
|
61
|
+
task :jruby do
|
62
|
+
sh "gem build wayfarer-jruby.gemspec --verbose"
|
63
|
+
sh "mkdir -p build"
|
64
|
+
sh "mv wayfarer-jruby-*.gem build"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "Remove build directory"
|
69
|
+
task :clean do
|
70
|
+
sh "rm -rf build"
|
71
|
+
end
|
72
|
+
|
73
|
+
desc "Start a preloaded REPL"
|
74
|
+
task :repl do
|
75
|
+
require_relative "lib/wayfarer"
|
76
|
+
|
77
|
+
include Wayfarer
|
78
|
+
include Wayfarer::HTTPAdapters
|
79
|
+
include Wayfarer::Routing
|
80
|
+
include Wayfarer::Frontiers
|
81
|
+
|
82
|
+
begin
|
83
|
+
require "pry"
|
84
|
+
Pry.new.repl(self)
|
85
|
+
rescue LoadError
|
86
|
+
require "irb"
|
87
|
+
ARGV.clear
|
88
|
+
IRB.start
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
desc %(List lines that contain "FIXME" or "TODO")
|
93
|
+
task :todo do
|
94
|
+
sh %(grep -rn "\\(FIXME\\|TODO\\)" lib spec | tr -s [:space:])
|
95
|
+
end
|
96
|
+
|
97
|
+
task :test_app do
|
98
|
+
mutex = Mutex.new
|
99
|
+
cvar = ConditionVariable.new
|
100
|
+
|
101
|
+
Thread.new do
|
102
|
+
Rack::Handler::WEBrick.run(
|
103
|
+
TestApp,
|
104
|
+
Port: 9876,
|
105
|
+
BindAddress: "localhost",
|
106
|
+
Logger: WEBrick::Log.new("/dev/null"),
|
107
|
+
AccessLog: [],
|
108
|
+
StartCallback: proc { cvar.signal }
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
mutex.lock
|
113
|
+
cvar.wait(mutex)
|
114
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../lib/wayfarer"
|
4
|
+
|
5
|
+
require "benchmark"
|
6
|
+
require "parallel" unless RUBY_PLATFORM == "java"
|
7
|
+
require "faker"
|
8
|
+
|
9
|
+
include Wayfarer::Frontiers
|
10
|
+
|
11
|
+
def print_separator
|
12
|
+
puts "-" * `tput cols`.to_i
|
13
|
+
end
|
14
|
+
|
15
|
+
# URI count is kept low on purpose because this file is run on Travis CI.
|
16
|
+
# Bump up the numbers when running locally.
|
17
|
+
URI_COUNT = 10_000
|
18
|
+
SAMPLE_COUNT = URI_COUNT * 0.01
|
19
|
+
CYCLE_COUNT = 20
|
20
|
+
|
21
|
+
FRONTIERS = RUBY_PLATFORM == "java" ? {
|
22
|
+
MemoryFrontier => "memory",
|
23
|
+
RedisFrontier => "redis"
|
24
|
+
} : {
|
25
|
+
MemoryBloomfilter => "memory_bloom",
|
26
|
+
MemoryFrontier => "memory",
|
27
|
+
MemoryTrieFrontier => "memory_trie",
|
28
|
+
RedisBloomfilter => "redis_bloom",
|
29
|
+
RedisFrontier => "redis"
|
30
|
+
}
|
31
|
+
|
32
|
+
label_width = FRONTIERS.reduce(0) { |acc, (_, label)|
|
33
|
+
acc > (l = label.length) ? acc : l
|
34
|
+
}
|
35
|
+
|
36
|
+
puts "Generating #{URI_COUNT} URIs..."
|
37
|
+
|
38
|
+
uris = if RUBY_PLATFORM == "java"
|
39
|
+
Array.new(URI_COUNT) { Faker::Internet.url }
|
40
|
+
else
|
41
|
+
Parallel.map(URI_COUNT.times) { Faker::Internet.url }
|
42
|
+
end
|
43
|
+
samples = uris.sample(SAMPLE_COUNT)
|
44
|
+
|
45
|
+
puts "Done generating URIs"
|
46
|
+
|
47
|
+
print_separator
|
48
|
+
puts "Cache insertion"
|
49
|
+
|
50
|
+
Benchmark.bm do |bm|
|
51
|
+
FRONTIERS.each do |(klass, label)|
|
52
|
+
frontier = klass.new(Wayfarer::Configuration.new)
|
53
|
+
frontier.cache(*uris)
|
54
|
+
|
55
|
+
bm.report(label.ljust(label_width)) do
|
56
|
+
frontier.cache(*samples)
|
57
|
+
end
|
58
|
+
|
59
|
+
frontier.free
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
print_separator
|
64
|
+
puts "Cache detection"
|
65
|
+
|
66
|
+
Benchmark.bm do |bm|
|
67
|
+
FRONTIERS.each do |(klass, label)|
|
68
|
+
frontier = klass.new(Wayfarer::Configuration.new)
|
69
|
+
frontier.cache(*uris)
|
70
|
+
|
71
|
+
bm.report(label.ljust(label_width)) do
|
72
|
+
samples.each { |sample| frontier.cached?(sample) }
|
73
|
+
end
|
74
|
+
|
75
|
+
frontier.free
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
print_separator
|
80
|
+
puts "Cycling"
|
81
|
+
|
82
|
+
slices = samples.each_slice(CYCLE_COUNT)
|
83
|
+
|
84
|
+
Benchmark.bm do |bm|
|
85
|
+
FRONTIERS.each do |(klass, label)|
|
86
|
+
frontier = klass.new(Wayfarer::Configuration.new)
|
87
|
+
|
88
|
+
bm.report(label.ljust(label_width)) do
|
89
|
+
slices.each do |samples|
|
90
|
+
frontier.stage(*samples)
|
91
|
+
frontier.cycle
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
frontier.free
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
print_separator
|
100
|
+
puts "Cache detection false positives/negatives"
|
101
|
+
|
102
|
+
trials = samples.count / 2
|
103
|
+
|
104
|
+
positives = samples.sample(trials)
|
105
|
+
negatives = if RUBY_PLATFORM == "java"
|
106
|
+
Array.new(trials) { Faker::Internet.url }
|
107
|
+
else
|
108
|
+
Parallel.map(trials.times) { Faker::Internet.url }
|
109
|
+
end
|
110
|
+
|
111
|
+
FRONTIERS.each do |(klass, label)|
|
112
|
+
frontier = klass.new(Wayfarer::Configuration.new)
|
113
|
+
|
114
|
+
false_positives = false_negatives = 0
|
115
|
+
|
116
|
+
positives.each do |positive| frontier.cache(positive) end
|
117
|
+
|
118
|
+
positives.each do |positive|
|
119
|
+
false_positives += 1 unless frontier.cached?(positive)
|
120
|
+
end
|
121
|
+
|
122
|
+
negatives.each do |negative|
|
123
|
+
false_positives += 1 if frontier.cached?(negative)
|
124
|
+
end
|
125
|
+
|
126
|
+
fp_percentage = if false_positives.zero?
|
127
|
+
0
|
128
|
+
else
|
129
|
+
(trials.to_f / false_positives).round(3)
|
130
|
+
end
|
131
|
+
|
132
|
+
fn_percentage = if false_negatives.zero?
|
133
|
+
0
|
134
|
+
else
|
135
|
+
(trials.to_f / false_negatives).round(3)
|
136
|
+
end
|
137
|
+
|
138
|
+
puts "* #{label.ljust(label_width)}"
|
139
|
+
puts " * False positives: #{false_positives} (#{fp_percentage}%)"
|
140
|
+
puts " * False negatives: #{false_negatives} (#{fn_percentage}%)"
|
141
|
+
|
142
|
+
frontier.free
|
143
|
+
end
|
data/bin/wayfarer
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "logger"
|
5
|
+
require "pathname"
|
6
|
+
require "time"
|
7
|
+
require "active_support/inflector"
|
8
|
+
require "thor"
|
9
|
+
|
10
|
+
require_relative "../lib/wayfarer"
|
11
|
+
|
12
|
+
module Wayfarer
|
13
|
+
class CLI < Thor
|
14
|
+
class_option :log_level, type: :string, default: "info"
|
15
|
+
|
16
|
+
desc "exec FILE URI",
|
17
|
+
"Run the job defined in FILE starting from URI(s)"
|
18
|
+
def exec(file, uri)
|
19
|
+
set_log_level(options)
|
20
|
+
load_class_from_file(file).perform(uri)
|
21
|
+
end
|
22
|
+
|
23
|
+
option :queue_adapter, type: :string, default: "inline"
|
24
|
+
option :wait, type: :string
|
25
|
+
desc "enqueue FILE URI",
|
26
|
+
"Run the job defined in FILE starting from URI(s)"
|
27
|
+
def enqueue(file, uri)
|
28
|
+
set_log_level(options)
|
29
|
+
set_queue_adapter(options)
|
30
|
+
|
31
|
+
if wait = options[:wait]
|
32
|
+
delayed_seconds = differing_seconds_from_string(wait)
|
33
|
+
load_class_from_file(file).set(wait: delayed_seconds).perform_later(uri)
|
34
|
+
else
|
35
|
+
load_class_from_file(file).perform_later(uri)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "route FILE URI",
|
40
|
+
"Output the first matching route from FILE for URI"
|
41
|
+
def route(file, uri)
|
42
|
+
set_log_level(options)
|
43
|
+
|
44
|
+
job = load_class_from_file(file)
|
45
|
+
|
46
|
+
action, params = job.router.route(URI(uri))
|
47
|
+
|
48
|
+
if action
|
49
|
+
puts "Dispatching to :#{action} with parameters: #{params}"
|
50
|
+
else
|
51
|
+
puts "No matching route"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "version", "Print the version"
|
56
|
+
def version
|
57
|
+
puts Wayfarer::VERSION
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def set_log_level(options)
|
63
|
+
if level = options[:log_level]
|
64
|
+
Wayfarer.log.level = log_level_from_string(level)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def set_queue_adapter(options)
|
69
|
+
if adapter = options[:queue_adapter]
|
70
|
+
ActiveJob::Base.queue_adapter = adapter
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def log_level_from_string(str)
|
75
|
+
case str.downcase
|
76
|
+
when "unknown" then Logger::UNKNOWN
|
77
|
+
when "debug" then Logger::DEBUG
|
78
|
+
when "error" then Logger::ERROR
|
79
|
+
when "fatal" then Logger::FATAL
|
80
|
+
when "info" then Logger::INFO
|
81
|
+
when "warn" then Logger::WARN
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def differing_seconds_from_string(str)
|
86
|
+
# RuboCop turned this into an art piece
|
87
|
+
if secs = begin
|
88
|
+
Integer(secs)
|
89
|
+
rescue
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
secs
|
93
|
+
elsif time = begin
|
94
|
+
Time.parse(str)
|
95
|
+
rescue
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
time - Time.now
|
99
|
+
else
|
100
|
+
# TODO: Get rid of this
|
101
|
+
require "chronic"
|
102
|
+
Chronic.parse(str) - Time.now
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def load_class_from_file(file)
|
107
|
+
path = File.join(Dir.pwd, file.chomp(".rb"))
|
108
|
+
base_name = Pathname.new(path).basename.to_s
|
109
|
+
|
110
|
+
require path
|
111
|
+
base_name.camelize.constantize
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
Wayfarer::CLI.start(ARGV)
|