grape-gen 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +31 -0
  6. data/Rakefile +2 -0
  7. data/bin/grape-gen +5 -0
  8. data/grape-scaffold.gemspec +24 -0
  9. data/lib/grape/generate/version.rb +5 -0
  10. data/lib/grape/generate.rb +91 -0
  11. data/template/Gemfile.tt +95 -0
  12. data/template/Guardfile +20 -0
  13. data/template/abilities/api_ability.rb +15 -0
  14. data/template/api/api_app.rb +85 -0
  15. data/template/api/mounts/auth.rb.tt +42 -0
  16. data/template/api/mounts/profile.rb.tt +24 -0
  17. data/template/config/application.yml.tt +33 -0
  18. data/template/config/boot.rb.tt +85 -0
  19. data/template/config/boot_faye.rb +22 -0
  20. data/template/config/boot_sidekiq.rb.tt +33 -0
  21. data/template/config/boot_spec.rb.tt +85 -0
  22. data/template/config/database.rb.tt +6 -0
  23. data/template/config/database.yml.tt +21 -0
  24. data/template/config/initializers/carrierwave.rb +3 -0
  25. data/template/config/initializers/core_ext.rb +14 -0
  26. data/template/config/initializers/em-patches/carrierwave.rb +13 -0
  27. data/template/config/initializers/em-patches/faye.rb +4 -0
  28. data/template/config/initializers/em-patches/lazy_evaluated_pool.rb +35 -0
  29. data/template/config/initializers/em-patches/mandrill.rb +45 -0
  30. data/template/config/initializers/em-patches/redis.rb +13 -0
  31. data/template/config/initializers/em-patches/redis_lazy_evaluated_pool.rb +19 -0
  32. data/template/config/initializers/em-patches/sidekiq.rb +46 -0
  33. data/template/config/initializers/em-patches/tire.rb +8 -0
  34. data/template/config/initializers/faye.rb +3 -0
  35. data/template/config/initializers/grape.rb +11 -0
  36. data/template/config/initializers/logging.rb +38 -0
  37. data/template/config/initializers/mandrill.rb +1 -0
  38. data/template/config/initializers/patches/redis_namespace.rb +96 -0
  39. data/template/config/initializers/sidekiq.rb +15 -0
  40. data/template/config/initializers/tire.rb +6 -0
  41. data/template/config/initializers/workflow.rb +31 -0
  42. data/template/config/logging.yml.tt +39 -0
  43. data/template/config/settings.rb +24 -0
  44. data/template/config/sidekiq.yml.tt +22 -0
  45. data/template/config.ru.tt +8 -0
  46. data/template/faye.ru +55 -0
  47. data/template/jobs/pong_time.rb +11 -0
  48. data/template/lib/faye_auth_extension.rb +61 -0
  49. data/template/lib/faye_publisher.rb +63 -0
  50. data/template/lib/mongoid/tire_plugin.rb +17 -0
  51. data/template/lib/warden/token_strategy.rb +18 -0
  52. data/template/mailers/registration_mailer.rb +17 -0
  53. data/template/models/user.rb.tt +75 -0
  54. data/template/public/faye.html +36 -0
  55. data/template/search_indexes/search_index.rb +60 -0
  56. data/template/search_indexes/user_index.rb +20 -0
  57. data/template/spec/api/mounts/auth_spec.rb.tt +37 -0
  58. data/template/spec/factories/user.rb +8 -0
  59. data/template/spec/spec_helper.rb.tt +132 -0
  60. data/template/uploaders/avatar_uploader.rb +23 -0
  61. data/template/views/v1/user/profile.json.jbuilder.tt +4 -0
  62. metadata +147 -0
@@ -0,0 +1,85 @@
1
+ # Defines our constants
2
+ RACK_ENV = ENV['RACK_ENV'] || 'development' unless defined?(RACK_ENV)
3
+ APP_ROOT = File.expand_path('../..', __FILE__) unless defined?(APP_ROOT)
4
+
5
+ # Load our dependencies
6
+ require 'rubygems' unless defined?(Gem)
7
+ require 'bundler/setup'
8
+ require 'yaml'
9
+
10
+ # Load initializers
11
+ Bundler.require(
12
+ :framework,
13
+ :db,
14
+ <% if @sidekiq -%>
15
+ :sidekiq,
16
+ <% end -%>
17
+ <% if @mandrill -%>
18
+ :mailer,
19
+ <% end -%>
20
+ :utils,
21
+ <% if @es -%>
22
+ :elastic_search,
23
+ <% end -%>
24
+ RACK_ENV
25
+ )
26
+
27
+ require_relative 'settings'
28
+
29
+ ApplicationSettings.source File.expand_path('config/application.yml', APP_ROOT)
30
+ ApplicationSettings.root = APP_ROOT
31
+
32
+ require_relative 'database'
33
+
34
+ Dir[ApplicationSettings.root('config/initializers/em-patches/*.rb')].each {|initializer| require initializer} unless RACK_ENV == 'test'
35
+ Dir[ApplicationSettings.root('config/initializers/*.rb')].each {|initializer|
36
+ require initializer unless initializer =~ /(faye|sidekiq|tire|mandrill)/
37
+ }
38
+ <% if @sidekiq %>
39
+ require 'sidekiq/testing'
40
+ <% end %>
41
+
42
+ <% if @dev_reload %>
43
+ RACK_APPLICATION = Grape::RackBuilder.setup do
44
+ %w{api models lib uploaders models abilities jobs search_indexes mailers}.each do |path|
45
+ add_source_path ApplicationSettings.root("#{path}/**/*.rb")
46
+ add_source_path ApplicationSettings.root("#{path}/*.rb")
47
+ end
48
+
49
+ use Warden::Manager do |config|
50
+ config.strategies.add(:access_token, TokenStrategy)
51
+ config.default_strategies :access_token
52
+ config.failure_app = API::Application
53
+ config.intercept_401 = false
54
+ end
55
+
56
+ use Rack::Config do |env|
57
+ env['api.tilt.root'] = ApplicationSettings.root('views')
58
+ end
59
+
60
+ mount 'API::Application', to: '/api'
61
+
62
+ logger Logging.logger[:rackbuilder]
63
+ end.boot!.application
64
+ <% else %>
65
+ %w{lib models uploaders models abilities jobs search_indexes mailers api}.each do |path|
66
+ Dir[ApplicationSettings.root("#{path}/**/*.rb")].each {|f| require f}
67
+ end
68
+
69
+ RACK_APPLICATION = Rack::Builder.new do
70
+ use Warden::Manager do |config|
71
+ config.strategies.add(:access_token, TokenStrategy)
72
+ config.default_strategies :access_token
73
+ config.failure_app = API::Application
74
+ config.intercept_401 = false
75
+ end
76
+
77
+ use Rack::Config do |env|
78
+ env['api.tilt.root'] = ApplicationSettings.root('views')
79
+ end
80
+
81
+ map '/api' do
82
+ run API::Application
83
+ end
84
+ end
85
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <%- case @orm
2
+ when 'mongoid' -%>
3
+ Mongoid.load!(ApplicationSettings.root('config', 'database.yml'), RACK_ENV)
4
+ Mongoid.logger = Logging.logger[:database]
5
+ Moped.logger = Logging.logger[:database]
6
+ <%- end -%>
@@ -0,0 +1,21 @@
1
+ development: &dev
2
+ sessions:
3
+ default:
4
+ database: <%= @app_name %>
5
+ hosts:
6
+ - 127.0.0.1
7
+
8
+ options:
9
+ pool_size: 100
10
+
11
+ production: *dev
12
+
13
+ test:
14
+ sessions:
15
+ default:
16
+ database: <%= @app_name %>_test
17
+ hosts:
18
+ - 127.0.0.1
19
+
20
+ options:
21
+ pool_size: 100
@@ -0,0 +1,3 @@
1
+ CarrierWave.configure do |config|
2
+ config.root = ApplicationSettings.root
3
+ end
@@ -0,0 +1,14 @@
1
+ class DateTime
2
+ alias_method :to_s, :iso8601
3
+ end
4
+
5
+ class Time
6
+ alias_method :to_s, :iso8601
7
+ end
8
+
9
+ class Hash
10
+ def pick(*keys)
11
+ keys = keys.first if keys.first.kind_of? Array
12
+ Hash[keys.zip(values_at(*keys))]
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ require 'em-synchrony'
2
+ require 'carrierwave/processing/mini_magick'
3
+
4
+ module CarrierWave
5
+ module MiniMagick
6
+ alias_method :old_manipulate!, :manipulate!
7
+ def manipulate!(&block)
8
+ EventMachine::Synchrony.defer do
9
+ old_manipulate!(&block)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ require_relative 'redis_lazy_evaluated_pool'
2
+ require_relative '../../../lib/faye_publisher'
3
+
4
+ FayePublisher.redis = RedisLazyEvaluatedPool.pool_with_config(ApplicationSettings.faye.redis.to_hash.deep_symbolize_keys)
@@ -0,0 +1,35 @@
1
+ require 'em-synchrony/connection_pool'
2
+
3
+ class LazyEvaluatedPool < EventMachine::Synchrony::ConnectionPool
4
+ def initialize(opts, &block)
5
+ @reserved = {} # map of in-progress connections
6
+ @available = [] # pool of free connections
7
+ @pending = [] # pending reservations (FIFO)
8
+ @config = opts
9
+ opts[:size].times do
10
+ @available.push(block) if block_given?
11
+ end
12
+ end
13
+
14
+ private
15
+ def acquire(fiber)
16
+ if conn = @available.pop
17
+ conn = self.instance_eval(&conn) if conn.respond_to?(:call)
18
+ @reserved[fiber.object_id] = conn
19
+ conn
20
+ else
21
+ Fiber.yield @pending.push fiber
22
+ acquire(fiber)
23
+ end
24
+ end
25
+
26
+ class << self
27
+ def pool_with_config(config, &block)
28
+ config[:size] ||= 10
29
+ LazyEvaluatedPool.new(config, &(block || connection))
30
+ end
31
+ private
32
+ def connection; raise 'Please, override connection method or supply block' end
33
+ end
34
+ end
35
+
@@ -0,0 +1,45 @@
1
+ # Patch mandrill API to play ball with EventMachine
2
+ module Mandrill
3
+ class API
4
+ def initialize(apikey=nil, debug=false)
5
+ @host = 'https://mandrillapp.com'
6
+ @path = '/api/1.0/'
7
+
8
+ @debug = debug
9
+
10
+ unless apikey
11
+ if ENV['MANDRILL_APIKEY']
12
+ apikey = ENV['MANDRILL_APIKEY']
13
+ else
14
+ apikey = read_configs
15
+ end
16
+ end
17
+
18
+ raise Error, 'You must provide a Mandrill API key' unless apikey
19
+ @apikey = apikey
20
+ end
21
+
22
+ def call(url, params={})
23
+ defer = EventMachine::DefaultDeferrable.new
24
+ params[:key] = @apikey
25
+ params = JSON.generate(params)
26
+ http = Mandrill::API.request.get(path: "#{@path}#{url}.json", headers: {'Content-Type' => 'application/json'}, body: params, keepalive: true)
27
+ http.callback do |r|
28
+ cast_error(r.response) if r.response_header.status != 200
29
+ defer.succeed(JSON.parse(r.response))
30
+ end
31
+
32
+ http.errback do |r|
33
+ raise Mandrill::ServiceUnavailableError.new
34
+ end
35
+
36
+ EventMachine::Synchrony.sync defer
37
+ end
38
+
39
+ class << self
40
+ def request
41
+ EventMachine::HttpRequest.new('https://mandrillapp.com/api/1.0/')
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ require 'em-synchrony/em-hiredis'
2
+
3
+ unless defined?(REDIS_CONNECTION)
4
+ module EventMachine
5
+ module Hiredis
6
+ class BaseClient
7
+ def async_command(*args)
8
+ old_method_missing(*args)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ require 'redis-namespace'
2
+ require_relative 'redis'
3
+ require_relative 'lazy_evaluated_pool'
4
+
5
+ class RedisLazyEvaluatedPool < LazyEvaluatedPool
6
+ CONFIG_DEFAULTS = {
7
+ url: 'redis://localhost:6379/0',
8
+ size: 10
9
+ }
10
+ private
11
+ def self.connection
12
+ Proc.new {
13
+ config = RedisLazyEvaluatedPool::CONFIG_DEFAULTS.merge (@config|| {}).deep_symbolize_keys
14
+ connection = EventMachine::Hiredis.connect(config[:url])
15
+ connection = Redis::Namespace.new(config[:namespace], redis: connection) if config[:namespace]
16
+ connection
17
+ }
18
+ end
19
+ end
@@ -0,0 +1,46 @@
1
+ require 'sidekiq'
2
+ require_relative 'redis'
3
+
4
+ module Sidekiq
5
+ def self.redis=(hash)
6
+ if hash.is_a?(LazyEvaluatedPool)
7
+ @redis = hash
8
+ else
9
+ @_config_hash = hash
10
+ end
11
+ end
12
+ class Client
13
+ private
14
+ def raw_push(payloads)
15
+ @redis_pool.execute(false) do |conn|
16
+ # No need to wait MULTI command to finish
17
+ conn.async_command :multi
18
+ # Atomic push commands is also async
19
+ atomic_push(conn, payloads)
20
+ # After pipeline is built, call synced EXEC command
21
+ conn.exec
22
+ end
23
+ true
24
+ end
25
+
26
+ def atomic_push(conn, payloads)
27
+ if payloads.first['at']
28
+ conn.async_command(:zadd, 'schedule',payloads.map do |hash|
29
+ at = hash.delete('at').to_s
30
+ [at, Sidekiq.dump_json(hash)]
31
+ end)
32
+ else
33
+ q = payloads.first['queue']
34
+ to_push = payloads.map { |entry| Sidekiq.dump_json(entry) }
35
+ conn.async_command(:sadd, 'queues', q)
36
+ conn.async_command(:lpush,"queue:#{q}", to_push)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ Sidekiq.configure_client do |config|
43
+ config.redis = RedisLazyEvaluatedPool.pool_with_config(ApplicationSettings.sidekiq.redis)
44
+ end
45
+
46
+ SIDEKIQ_ON_EM = true
@@ -0,0 +1,8 @@
1
+ require 'tire/http/clients/faraday'
2
+
3
+ Tire.configure do
4
+ Tire::HTTP::Client::Faraday.faraday_middleware = Proc.new do |builder|
5
+ builder.adapter :em_synchrony
6
+ end
7
+ client Tire::HTTP::Client::Faraday
8
+ end
@@ -0,0 +1,3 @@
1
+ require_relative '../../lib/faye_publisher'
2
+
3
+ FayePublisher.redis = ApplicationSettings.faye.redis unless FayePublisher.configured?
@@ -0,0 +1,11 @@
1
+ module Grape
2
+ module Formatter
3
+ module Json
4
+ class << self
5
+ def call(object, env)
6
+ MultiJson.dump(object)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,38 @@
1
+ require 'logging'
2
+
3
+ logger_config = YAML.load(File.read(ApplicationSettings.root('config/logging.yml')))[RACK_ENV.to_s].deep_symbolize_keys
4
+
5
+ apply_logger_config = ->(logger, config, buffering_options) do
6
+ logger.level = config[:level] || :debug
7
+ logger.additive = config[:additive] if logger.respond_to? 'additive='
8
+ logger.add_appenders(
9
+ (config[:appenders] || { default: {type: 'stdout'} }).map do |key, value|
10
+ case value
11
+ when String
12
+ Logging.appenders.send(key, value, buffering_options)
13
+ when Hash
14
+ layout = value.delete(:layout)
15
+ if layout
16
+ if layout.kind_of? String
17
+ value[:layout] = Logging.layouts.pattern(pattern: layout)
18
+ else
19
+ layout_type = layout.delete(:type) || :basic
20
+ value[:layout] = Logging.layouts.send(layout_type, layout)
21
+ end
22
+ end
23
+
24
+ Logging.appenders.send(value[:type] || key, logger.name, buffering_options.merge!(value).symbolize_keys!)
25
+ else
26
+ Logging.appenders.send(key, logger.name, buffering_options)
27
+ end
28
+ end
29
+ )
30
+ end
31
+
32
+ buferring_options = [:auto_flushing, :immediate_at, :flush_period]
33
+ bufferring = Hash[buferring_options.zip(logger_config.values_at(*buferring_options))]
34
+ routes = logger_config.delete(:routes) || []
35
+
36
+ apply_logger_config.call(Logging.logger.root, logger_config, bufferring)
37
+
38
+ routes.each { |route, settings| apply_logger_config.call(Logging.logger[route], settings, bufferring) }
@@ -0,0 +1 @@
1
+ MandrillMailer.config.api = ApplicationSettings.mandrill.api_key
@@ -0,0 +1,96 @@
1
+ class Redis
2
+ class Namespace
3
+ def call_with_namespace(command, *args, &block)
4
+ handling = COMMANDS[command.to_s.downcase]
5
+
6
+ if handling.nil?
7
+ fail("Redis::Namespace does not know how to handle '#{command}'.")
8
+ end
9
+
10
+ (before, after) = handling
11
+
12
+ # Add the namespace to any parameters that are keys.
13
+ case before
14
+ when :first
15
+ args[0] = add_namespace(args[0]) if args[0]
16
+ when :all
17
+ args = add_namespace(args)
18
+ when :exclude_first
19
+ first = args.shift
20
+ args = add_namespace(args)
21
+ args.unshift(first) if first
22
+ when :exclude_last
23
+ last = args.pop unless args.length == 1
24
+ args = add_namespace(args)
25
+ args.push(last) if last
26
+ when :exclude_options
27
+ if args.last.is_a?(Hash)
28
+ last = args.pop
29
+ args = add_namespace(args)
30
+ args.push(last)
31
+ else
32
+ args = add_namespace(args)
33
+ end
34
+ when :alternate
35
+ args.each_with_index { |a, i| args[i] = add_namespace(a) if i.even? }
36
+ when :sort
37
+ args[0] = add_namespace(args[0]) if args[0]
38
+ if args[1].is_a?(Hash)
39
+ [:by, :store].each do |key|
40
+ args[1][key] = add_namespace(args[1][key]) if args[1][key]
41
+ end
42
+
43
+ args[1][:get] = Array(args[1][:get])
44
+
45
+ args[1][:get].each_index do |i|
46
+ args[1][:get][i] = add_namespace(args[1][:get][i]) unless args[1][:get][i] == "#"
47
+ end
48
+ end
49
+ when :eval_style
50
+ # redis.eval() and evalsha() can either take the form:
51
+ #
52
+ # redis.eval(script, [key1, key2], [argv1, argv2])
53
+ #
54
+ # Or:
55
+ #
56
+ # redis.eval(script, :keys => ['k1', 'k2'], :argv => ['arg1', 'arg2'])
57
+ #
58
+ # This is a tricky + annoying special case, where we only want the `keys`
59
+ # argument to be namespaced.
60
+ if args.last.is_a?(Hash)
61
+ args.last[:keys] = add_namespace(args.last[:keys])
62
+ else
63
+ args[1] = add_namespace(args[1])
64
+ end
65
+ when :scan_style
66
+ options = (args.last.kind_of?(Hash) ? args.pop : {})
67
+ options[:match] = add_namespace(options.fetch(:match, '*'))
68
+ args << options
69
+
70
+ if block
71
+ original_block = block
72
+ block = proc { |key| original_block.call rem_namespace(key) }
73
+ end
74
+ end
75
+
76
+ d = EventMachine::DefaultDeferrable.new
77
+
78
+ # Dispatch the command to Redis and store the result.
79
+ result = @redis.send(command, *args, &block)
80
+
81
+ result.callback do |result|
82
+ case after
83
+ when :all
84
+ result = rem_namespace(result)
85
+ when :first
86
+ result[0] = rem_namespace(result[0]) if result
87
+ when :second
88
+ result[1] = rem_namespace(result[1]) if result
89
+ end
90
+ d.succeed(result)
91
+ end
92
+
93
+ d
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,15 @@
1
+ require 'redis-namespace'
2
+
3
+ if RACK_ENV == 'test'
4
+ require 'sidekiq/testing'
5
+ Sidekiq::Testing.fake!
6
+ else
7
+ Sidekiq.configure_server do |config|
8
+ config.redis = ApplicationSettings.sidekiq.redis
9
+ end
10
+
11
+ Sidekiq.configure_client do |config|
12
+ config.redis = ApplicationSettings.sidekiq.redis unless defined?(SIDEKIQ_ON_EM)
13
+ end
14
+ end
15
+ Sidekiq::Logging.logger = Logging.logger[:sidekiq]
@@ -0,0 +1,6 @@
1
+ require 'tire/http/clients/faraday'
2
+
3
+ Tire.configure do
4
+ url ApplicationSettings.elasticsearch.url
5
+ logger Logging.logger[:elasticsearch]
6
+ end
@@ -0,0 +1,31 @@
1
+ module Workflow
2
+ module Adapter
3
+ module Mongoid
4
+ def self.included(klass)
5
+ klass.send :include, InstanceMethods
6
+ end
7
+ module InstanceMethods
8
+ def load_workflow_state
9
+ send(self.class.workflow_column)
10
+ end
11
+
12
+ def persist_workflow_state(new_value)
13
+ update_attributes(self.class.workflow_column => new_value)
14
+ end
15
+
16
+ def before_validation
17
+ attributes[self.class.workflow_column] = current_state.to_s
18
+ super
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ module Mongoid
26
+ module Document
27
+ module ClassMethods
28
+ def workflow_adapter; Workflow::Adapter::Mongoid end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,39 @@
1
+ development: &dev
2
+ # Autoflush logs after 100 messages
3
+ auto_flushing: 1
4
+ # Flush logs each N seconds, empty to disable
5
+ flush_period:
6
+ # Log all levels by default
7
+ level: :debug
8
+ # Root appenders
9
+ appenders:
10
+ stdout: true
11
+
12
+ production:
13
+ # Flush logs each N seconds, empty to disable
14
+ flush_period: 3
15
+ immediate_at:
16
+ - :exception
17
+ - :error
18
+ - :fatal
19
+ level: :fatal
20
+
21
+ routes:
22
+ database:
23
+ additive: false
24
+ level: :debug
25
+ appenders:
26
+ default:
27
+ type: rolling_file
28
+ filename: log/database.log
29
+ <% if @faye %>
30
+ faye:
31
+ additive: false
32
+ level: :debug
33
+ appenders:
34
+ default:
35
+ type: rolling_file
36
+ filename: log/faye.log
37
+ <% end %>
38
+
39
+ test: *dev
@@ -0,0 +1,24 @@
1
+ require 'logging'
2
+ require 'settingslogic'
3
+ Logging.init :devel, :debug, :response, :info, :warn, :error, :fatal
4
+
5
+ class ApplicationSettings < Settingslogic
6
+ namespace RACK_ENV.to_s
7
+ class << self
8
+ def root=(value)
9
+ instance[:app_root] = value
10
+ end
11
+
12
+ def root(*path)
13
+ return File.expand_path(File.join(path), instance[:app_root]) if path
14
+ instance[:app_root]
15
+ end
16
+
17
+ # @return [String]
18
+ def api_absolute_url(uri)
19
+ "#{api_root}#{uri}"
20
+ end
21
+
22
+ # @return [String]
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ ---
2
+ :concurrency: 3
3
+ :pidfile: tmp/pids/sidekiq.pid
4
+ development:
5
+ :concurrency: 3
6
+ production:
7
+ :concurrency: 3
8
+ :queues:
9
+ - default
10
+ :schedule:
11
+ # 'DelayedJobs::YourJob':
12
+ # every: 10s
13
+ # queue: default
14
+ # description: Sample job schedule
15
+ <% if @faye %>
16
+ 'DelayedJobs::PongTime':
17
+ every: 5s
18
+ queue: default
19
+ description: Notify connected faye users about current time
20
+ <% end %>
21
+
22
+
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rackup -s thin
2
+ require_relative 'config/boot'
3
+
4
+ use Rack::Static, urls: {'/faye' => 'faye.html'}, root: 'public'
5
+
6
+ use Rack::FiberPool, size: 50
7
+
8
+ run RACK_APPLICATION