fluq 0.7.5 → 0.8.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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +12 -1
  5. data/Gemfile.lock +44 -8
  6. data/README.md +24 -6
  7. data/Rakefile +8 -1
  8. data/benchmark/socket.rb +13 -25
  9. data/examples/config/multi.rb +52 -0
  10. data/examples/config/simple.rb +15 -0
  11. data/fluq.gemspec +3 -3
  12. data/lib/fluq.rb +22 -16
  13. data/lib/fluq/cli.rb +3 -12
  14. data/lib/fluq/dsl.rb +2 -45
  15. data/lib/fluq/dsl/base.rb +11 -0
  16. data/lib/fluq/dsl/feed.rb +24 -0
  17. data/lib/fluq/dsl/root.rb +35 -0
  18. data/lib/fluq/event.rb +9 -28
  19. data/lib/fluq/feed.rb +40 -5
  20. data/lib/fluq/format.rb +6 -0
  21. data/lib/fluq/format/base.rb +42 -0
  22. data/lib/fluq/format/json.rb +17 -0
  23. data/lib/fluq/format/lines.rb +27 -0
  24. data/lib/fluq/format/msgpack.rb +28 -0
  25. data/lib/fluq/format/tsv.rb +19 -0
  26. data/lib/fluq/handler.rb +1 -1
  27. data/lib/fluq/handler/base.rb +11 -38
  28. data/lib/fluq/handler/log.rb +12 -14
  29. data/lib/fluq/handler/noop.rb +2 -0
  30. data/lib/fluq/input/base.rb +33 -29
  31. data/lib/fluq/input/socket.rb +46 -16
  32. data/lib/fluq/mixins.rb +2 -2
  33. data/lib/fluq/runner.rb +41 -0
  34. data/lib/fluq/testing.rb +5 -11
  35. data/lib/fluq/version.rb +1 -1
  36. data/lib/fluq/worker.rb +73 -0
  37. data/spec/fluq/dsl/feed_spec.rb +33 -0
  38. data/spec/fluq/dsl/root_spec.rb +20 -0
  39. data/spec/fluq/event_spec.rb +17 -12
  40. data/spec/fluq/feed_spec.rb +24 -0
  41. data/spec/fluq/format/base_spec.rb +9 -0
  42. data/spec/fluq/format/json_spec.rb +22 -0
  43. data/spec/fluq/format/lines_spec.rb +20 -0
  44. data/spec/fluq/format/msgpack_spec.rb +22 -0
  45. data/spec/fluq/format/tsv_spec.rb +21 -0
  46. data/spec/fluq/handler/base_spec.rb +7 -52
  47. data/spec/fluq/handler/log_spec.rb +11 -14
  48. data/spec/fluq/handler/{null_spec.rb → noop_spec.rb} +1 -3
  49. data/spec/fluq/input/base_spec.rb +48 -15
  50. data/spec/fluq/input/socket_spec.rb +34 -26
  51. data/spec/fluq/mixins/loggable_spec.rb +2 -2
  52. data/spec/fluq/runner_spec.rb +18 -0
  53. data/spec/fluq/worker_spec.rb +87 -0
  54. data/spec/fluq_spec.rb +1 -2
  55. data/spec/scenario/config/nested/feed1.rb +6 -0
  56. data/spec/scenario/config/test.rb +8 -2
  57. data/spec/spec_helper.rb +7 -26
  58. metadata +62 -62
  59. data/benchmark/logging.rb +0 -37
  60. data/examples/common.rb +0 -3
  61. data/examples/simple.rb +0 -5
  62. data/lib/fluq/buffer.rb +0 -6
  63. data/lib/fluq/buffer/base.rb +0 -51
  64. data/lib/fluq/buffer/file.rb +0 -68
  65. data/lib/fluq/feed/base.rb +0 -37
  66. data/lib/fluq/feed/json.rb +0 -28
  67. data/lib/fluq/feed/msgpack.rb +0 -27
  68. data/lib/fluq/feed/tsv.rb +0 -30
  69. data/lib/fluq/handler/null.rb +0 -4
  70. data/lib/fluq/input/socket/connection.rb +0 -41
  71. data/lib/fluq/mixins/logger.rb +0 -26
  72. data/lib/fluq/reactor.rb +0 -79
  73. data/spec/fluq/buffer/base_spec.rb +0 -21
  74. data/spec/fluq/buffer/file_spec.rb +0 -47
  75. data/spec/fluq/dsl_spec.rb +0 -43
  76. data/spec/fluq/feed/base_spec.rb +0 -15
  77. data/spec/fluq/feed/json_spec.rb +0 -27
  78. data/spec/fluq/feed/msgpack_spec.rb +0 -27
  79. data/spec/fluq/feed/tsv_spec.rb +0 -27
  80. data/spec/fluq/input/socket/connection_spec.rb +0 -35
  81. data/spec/fluq/mixins/logger_spec.rb +0 -25
  82. data/spec/fluq/reactor_spec.rb +0 -69
  83. data/spec/scenario/config/nested/common.rb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dd0315737359aba13bf67dc4ac588f57a12fedb4
4
- data.tar.gz: 0f5456c2087986cd3a80561c9d756cafe05b52ca
3
+ metadata.gz: 7820b9f9dfe9f91d1e8b3939363fa6471b2b233e
4
+ data.tar.gz: 3f8c2e1c3160e2db2f6f1f2c78496b759c536bd1
5
5
  SHA512:
6
- metadata.gz: 01a1b080eb885a520b7517cda04157d8374f02b232ed09175a0345cb5259320c91242f3d223d06731f73cb0d11b0fc62fc35aa9b8d4dca0b2c5ff649431892f4
7
- data.tar.gz: d6eac4e626670db21f1b3b89949924b74ab0a2e2ab74571b8a388d37904e9eeb6887e71cc73e42bb8f90fbc8620c11304b50b49e31f9e0c2a6e9047835a8a69c
6
+ metadata.gz: d5292f948e9c5b97d13acfd6822778586f812c7a40ab19122cf59b476443246ae5276f1eea07fb6daad9ce344edc70fe0f9873624e376910fe9513cf6a27ae5a
7
+ data.tar.gz: 486b08a58d7aaabf5c73af6ab525aec4b743079fa45247907c34b1c8d78dc1e47e5199436bec376f733c9cfad5f7713663c329c060ac40c7c4d7f9e26d406e38
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
1
  log/
2
2
  tmp/
3
3
  *.gem
4
+ .bundle
5
+ coverage/
data/.travis.yml CHANGED
@@ -2,5 +2,8 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
+ - 2.1.0
6
+ - jruby-19mode
5
7
  gemfile:
6
8
  - Gemfile
9
+ script: bundle exec rake spec:coveralls
data/Gemfile CHANGED
@@ -1,6 +1,17 @@
1
1
  source "https://rubygems.org"
2
2
  gemspec
3
3
 
4
- group :development do
4
+ platform :ruby do
5
5
  gem "oj"
6
+ gem "msgpack"
7
+ end
8
+
9
+ platform :jruby do
10
+ gem "jrjackson"
11
+ gem "msgpack-jruby"
12
+ end
13
+
14
+ platform :rbx do
15
+ gem "rubysl-logger"
16
+ gem "rubysl-singleton"
6
17
  end
data/Gemfile.lock CHANGED
@@ -1,20 +1,38 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluq (0.7.5)
5
- eventmachine-le
6
- msgpack (~> 0.5.0)
7
- oj (>= 2.0.10)
4
+ fluq (0.8.0)
5
+ celluloid-io (~> 0.15.0)
6
+ multi_json
8
7
  timed_lru
9
8
 
10
9
  GEM
11
10
  remote: https://rubygems.org/
12
11
  specs:
12
+ celluloid (0.15.2)
13
+ timers (~> 1.1.0)
14
+ celluloid-io (0.15.0)
15
+ celluloid (>= 0.15.0)
16
+ nio4r (>= 0.5.0)
17
+ coveralls (0.7.0)
18
+ multi_json (~> 1.3)
19
+ rest-client
20
+ simplecov (>= 0.7)
21
+ term-ansicolor
22
+ thor
13
23
  diff-lcs (1.2.5)
14
- eventmachine-le (1.1.6)
15
- msgpack (0.5.7)
16
- oj (2.2.2)
17
- rake (10.1.0)
24
+ docile (1.1.2)
25
+ jrjackson (0.2.6)
26
+ mime-types (2.1)
27
+ msgpack (0.5.8)
28
+ msgpack-jruby (1.3.2-java)
29
+ multi_json (1.8.4)
30
+ nio4r (1.0.0)
31
+ nio4r (1.0.0-java)
32
+ oj (2.5.4)
33
+ rake (10.1.1)
34
+ rest-client (1.6.7)
35
+ mime-types (>= 1.16)
18
36
  rspec (2.14.1)
19
37
  rspec-core (~> 2.14.0)
20
38
  rspec-expectations (~> 2.14.0)
@@ -23,7 +41,19 @@ GEM
23
41
  rspec-expectations (2.14.4)
24
42
  diff-lcs (>= 1.1.3, < 2.0)
25
43
  rspec-mocks (2.14.4)
44
+ rubysl-logger (2.0.0)
45
+ rubysl-singleton (2.0.0)
46
+ simplecov (0.8.2)
47
+ docile (~> 1.1.0)
48
+ multi_json
49
+ simplecov-html (~> 0.8.0)
50
+ simplecov-html (0.8.0)
51
+ term-ansicolor (1.2.2)
52
+ tins (~> 0.8)
53
+ thor (0.18.1)
26
54
  timed_lru (0.3.1)
55
+ timers (1.1.0)
56
+ tins (0.13.1)
27
57
  yard (0.8.7.3)
28
58
 
29
59
  PLATFORMS
@@ -32,8 +62,14 @@ PLATFORMS
32
62
 
33
63
  DEPENDENCIES
34
64
  bundler
65
+ coveralls
35
66
  fluq!
67
+ jrjackson
68
+ msgpack
69
+ msgpack-jruby
36
70
  oj
37
71
  rake
38
72
  rspec
73
+ rubysl-logger
74
+ rubysl-singleton
39
75
  yard
data/README.md CHANGED
@@ -1,10 +1,28 @@
1
- FluQ
2
- ====
1
+ # FluQ [![Build Status](https://travis-ci.org/bsm/fluq.png?branch=master)](https://travis-ci.org/bsm/fluq) [![Coverage Status](https://coveralls.io/repos/bsm/fluq/badge.png)](https://coveralls.io/r/bsm/fluq)
3
2
 
4
3
  Description coming soon ...
5
4
 
6
- Licence
7
- -------
5
+ ## Licence
8
6
 
9
- Copyright 2013 Black Square Media Ltd.
10
- It is free software, and may be redistributed under the terms specified in the MIT-LICENCE file.
7
+ ```
8
+ Copyright (c) 2014 Black Square Media
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining
11
+ a copy of this software and associated documentation files (the
12
+ "Software"), to deal in the Software without restriction, including
13
+ without limitation the rights to use, copy, modify, merge, publish,
14
+ distribute, sublicense, and/or sell copies of the Software, and to
15
+ permit persons to whom the Software is furnished to do so, subject to
16
+ the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be
19
+ included in all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
+ ```
data/Rakefile CHANGED
@@ -1,11 +1,18 @@
1
1
  require 'rake'
2
+ require 'bundler/gem_tasks'
2
3
 
3
- require 'rspec/mocks/version'
4
4
  require 'rspec/core/rake_task'
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
7
  require 'yard'
8
+ require 'yard/rake/yardoc_task'
8
9
  YARD::Rake::YardocTask.new
9
10
 
11
+ require 'coveralls/rake/task'
12
+ Coveralls::RakeTask.new
13
+ namespace :spec do
14
+ task coveralls: [:spec, 'coveralls:push']
15
+ end
16
+
10
17
  desc 'Default: run specs.'
11
18
  task :default => :spec
data/benchmark/socket.rb CHANGED
@@ -8,45 +8,33 @@ require 'fluq'
8
8
  BATCH_SIZE = 100_000
9
9
  BATCHES = 50
10
10
  ROOT = FluQ.root.join("log/benchmark")
11
- EVENT = FluQ::Event.new("a.b.c.d", Time.now.to_i, "k1" => "value", "k2" => "value", "k3" => "value").to_msgpack
11
+ EVENT = MessagePack.pack("k1" => "value", "k2" => "value", "k3" => "value")
12
12
 
13
13
  FileUtils.rm_rf ROOT.to_s
14
14
  FileUtils.mkdir_p ROOT.to_s
15
+ FluQ.logger.level = Logger::ERROR
15
16
 
16
- class FluQ::Handler::Counter < FluQ::Handler::Base
17
- attr_reader :count
18
- def initialize(*)
19
- super
20
- @count = 0
21
- end
22
- def on_events(events)
23
- @count += events.size
24
- EM.stop if @count >= BATCHES * BATCH_SIZE
17
+ puts "--> Preparing"
18
+ Thread.new do
19
+ FluQ::Runner.run do |run|
20
+ run.feed :test do |feed|
21
+ feed.register FluQ::Handler::Noop
22
+ feed.listen FluQ::Input::Socket, bind: "tcp://127.0.0.1:8765", format: :msgpack
23
+ end
25
24
  end
26
25
  end
27
-
28
- puts "--> Preparing"
29
26
  BATCHES.times do |i|
30
27
  ROOT.join("batch.#{i}").open("wb:ASCII-8BIT") do |file|
31
28
  BATCH_SIZE.times { file.write(EVENT) }
32
29
  end
33
30
  end
34
31
 
35
- processed = 0
36
- handler = nil
37
- start = Time.now
38
- FluQ::Reactor.run do |reactor|
39
- reactor.listen FluQ::Input::Socket, bind: "tcp://127.0.0.1:8765"
40
- handler = reactor.register FluQ::Handler::Counter
41
-
42
- sleep(0.1)
32
+ puts "--> Started benchmark"
33
+ 2.times do
43
34
  start = Time.now
44
- puts "--> Started benchmark"
45
35
  BATCHES.times do |i|
46
36
  file = ROOT.join("batch.#{i}")
47
- spawn("nc 127.0.0.1 8765 < #{file}")
37
+ system "nc 127.0.0.1 8765 < #{file}"
48
38
  end
39
+ puts "--> Processed : #{BATCHES * BATCH_SIZE} in #{(Time.now - start).round(1)}s"
49
40
  end
50
-
51
- puts "--> Accepted : #{BATCHES * BATCH_SIZE} in #{(Time.now - start).round(1)}s"
52
- puts "--> Processed : #{handler.count} events"
@@ -0,0 +1,52 @@
1
+ # Main feed
2
+ feed "main" do
3
+
4
+ # Listen on a UDP socket
5
+ input :socket do
6
+ bind "udp://127.0.0.1:6789"
7
+ format :json
8
+ end
9
+
10
+ # Log all events to a path
11
+ handler :log do
12
+ path "/var/log/main/%Y%m%d/%H.log"
13
+ end
14
+
15
+ end
16
+
17
+ # Priority feed
18
+ feed "priority" do
19
+
20
+ # Listen on a TCP socket
21
+ input :socket do
22
+ bind "tcp://127.0.0.1:6789"
23
+ format :json
24
+ end
25
+
26
+ # Pull Kafka topic (requires fluq-kafka Gem)
27
+ input :kafka do
28
+ topic "orders"
29
+ brokers ["host1:9092", "host2:9092"]
30
+ zookeepers ["host1:2181", "host2:2181"]
31
+ format :msgpack
32
+ end
33
+
34
+ # Pull another Kafka topic
35
+ input :kafka do
36
+ topic "deliveries"
37
+ brokers ["host1:9092", "host2:9092"]
38
+ zookeepers ["host1:2181", "host2:2181"]
39
+ format :msgpack
40
+ end
41
+
42
+ # Log all events to a path
43
+ handler :log do
44
+ path "/var/log/priority/%Y%m%d/%H.log"
45
+ end
46
+
47
+ # Use your own custom handler to e.g. send notification emails
48
+ handler :email do
49
+ to "relevant.party@example.com"
50
+ end
51
+
52
+ end
@@ -0,0 +1,15 @@
1
+ # Feed definition: a feed 'wraps' a list of inputs and a list of handler
2
+ feed "my-feed" do
3
+
4
+ # Listen on a TCP socket for JSON formatted messages
5
+ input :socket do
6
+ bind "tcp://127.0.0.1:6789"
7
+ format :json
8
+ end
9
+
10
+ # Log all events to a timestamped path
11
+ handler :log do
12
+ path "/var/log/%Y%m%d/%H.log"
13
+ end
14
+
15
+ end
data/fluq.gemspec CHANGED
@@ -22,13 +22,13 @@ Gem::Specification.new do |s|
22
22
  s.files = `git ls-files`.split("\n")
23
23
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
24
 
25
- s.add_dependency "msgpack", "~> 0.5.0"
26
- s.add_dependency "eventmachine-le"
27
- s.add_dependency "oj", ">= 2.0.10"
25
+ s.add_dependency "celluloid-io", "~> 0.15.0"
28
26
  s.add_dependency "timed_lru"
27
+ s.add_dependency "multi_json"
29
28
 
30
29
  s.add_development_dependency "rake"
31
30
  s.add_development_dependency "bundler"
32
31
  s.add_development_dependency "rspec"
33
32
  s.add_development_dependency "yard"
33
+ s.add_development_dependency "coveralls"
34
34
  end
data/lib/fluq.rb CHANGED
@@ -1,14 +1,21 @@
1
1
  require 'pathname'
2
2
  require 'uri'
3
3
  require 'fileutils'
4
+ require 'stringio'
5
+ require 'thread'
4
6
  require 'securerandom'
5
7
  require 'forwardable'
6
8
  require 'logger'
7
- require 'eventmachine'
8
- require 'msgpack'
9
- require 'oj'
10
- require 'timed_lru'
11
9
  require 'timeout'
10
+ require 'timed_lru'
11
+ require 'celluloid/io'
12
+ require 'celluloid/autostart'
13
+ require 'multi_json'
14
+
15
+ begin
16
+ require 'msgpack'
17
+ rescue LoadError
18
+ end
12
19
 
13
20
  module FluQ
14
21
  %w'version error mixins'.each do |name|
@@ -17,27 +24,26 @@ module FluQ
17
24
 
18
25
  class << self
19
26
 
20
- # @attr_reader [String] env runtime environemnt
21
27
  # @attr_reader [Pathname] root project root
22
- # @attr_reader [Logger] logger the main logger
23
- attr_reader :env, :root, :logger
28
+ attr_reader :root
24
29
 
25
- # @param [Logger] instance the thread-safe logger instance
26
- def logger=(instance)
27
- instance.extend(FluQ::Mixins::Logger)
28
- @logger = instance
30
+ # @param [Logger] logger
31
+ def logger=(logger)
32
+ Celluloid.logger = logger
29
33
  end
30
34
 
31
- def init!
32
- # Detect environment
33
- @env = ENV['FLUQ_ENV'] || "development"
35
+ # @return [Logger] the thread-safe logger instance
36
+ def logger
37
+ Celluloid.logger
38
+ end
34
39
 
40
+ def init!
35
41
  # Set root path
36
42
  @root = Pathname.new(ENV['FLUQ_ROOT'] || ".")
37
43
 
38
44
  # Setup logger
39
45
  self.logger = ::Logger.new(STDOUT)
40
- logger.level = ::Logger::INFO if env == "production"
46
+ logger.level = ::Logger::INFO
41
47
  end
42
48
  protected :init!
43
49
 
@@ -46,6 +52,6 @@ module FluQ
46
52
  init!
47
53
  end
48
54
 
49
- %w'url event reactor handler input buffer feed dsl'.each do |name|
55
+ %w'url event runner feed worker handler input format dsl'.each do |name|
50
56
  require "fluq/#{name}"
51
57
  end
data/lib/fluq/cli.rb CHANGED
@@ -33,11 +33,6 @@ module FluQ
33
33
  exit
34
34
  end
35
35
 
36
- # Set the environment
37
- if options[:env]
38
- ENV["FLUQ_ENV"] = options[:env]
39
- end
40
-
41
36
  # Boot and add project's lib/ dir to load path
42
37
  require 'fluq'
43
38
  $LOAD_PATH.unshift FluQ.root.join('lib')
@@ -63,9 +58,9 @@ module FluQ
63
58
  end
64
59
 
65
60
  # Start
66
- log "Starting FluQ #{FluQ::VERSION} (#{FluQ.env})"
67
- FluQ::Reactor.run do |reactor|
68
- FluQ::DSL.new(reactor, options[:config]).run
61
+ log "Starting FluQ #{FluQ::VERSION} (#{options[:config]})"
62
+ FluQ::Runner.run do |runner|
63
+ FluQ::DSL::Root.new(options[:config]).apply(runner)
69
64
  procline
70
65
  end
71
66
  end
@@ -106,10 +101,6 @@ module FluQ
106
101
  o.separator ""
107
102
  o.separator "Optional:"
108
103
 
109
- o.on("-e", "--environment ENV", "Runtime environment (default: development)") do |val|
110
- @options[:env] = val
111
- end
112
-
113
104
  o.on("-l", "--log FILE", "File to log to (default: STDOUT)") do |val|
114
105
  @options[:log] = val
115
106
  end
data/lib/fluq/dsl.rb CHANGED
@@ -1,49 +1,6 @@
1
- class FluQ::DSL
2
- attr_reader :path, :reactor, :inputs, :handlers
3
-
4
- # @param [FluQ::Reactor] reactor
5
- # @param [String] DSL script file path
6
- def initialize(reactor, path)
7
- @reactor = reactor
8
- @path = Pathname.new(path)
9
- @inputs = []
10
- @handlers = []
11
- end
12
-
13
- # @param [Array<Symbol>] input type path, e.g. :socket
14
- def input(*type, &block)
15
- klass = constantize(:input, *type)
16
- inputs.push [klass, FluQ::DSL::Options.new(&block).to_hash]
17
- end
18
-
19
- # @param [Array<Symbol>] handler type path, e.g. :log, :counter
20
- def handler(*type, &block)
21
- klass = constantize(:handler, *type)
22
- handlers.push [klass, FluQ::DSL::Options.new(&block).to_hash]
23
- end
24
-
25
- # @param [String] relative relative path
26
- def import(relative)
27
- instance_eval(path.dirname.join(relative).read)
28
- end
29
-
30
- # Starts the components. Handlers first, then inputs.
31
- def run
32
- instance_eval(path.read)
33
- handlers.each {|klass, options| reactor.register(klass, options) }
34
- inputs.each {|klass, options| reactor.listen(klass, options) }
35
- end
36
-
37
- protected
38
-
39
- def constantize(*path)
40
- require([:fluq, *path].join('/'))
41
- names = path.map {|p| p.to_s.split('_').map(&:capitalize).join }
42
- names.inject(FluQ) {|klass, name| klass.const_get(name) }
43
- end
44
-
1
+ module FluQ::DSL
45
2
  end
46
3
 
47
- %w'options'.each do |name|
4
+ %w'base root feed options'.each do |name|
48
5
  require "fluq/dsl/#{name}"
49
6
  end