Class: Communist::Server

Inherits:
Object
  • Object
show all
Includes:
Const
Defined in:
lib/communist/server.rb

Defined Under Namespace

Classes: Identify, ServerError

Constant Summary

Constants included from Const

Const::DEFAULT_HOST, Const::DEFAULT_TIMEOUT

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ Server

Returns a new instance of Server.



37
38
39
40
41
42
43
44
# File 'lib/communist/server.rb', line 37

def initialize(app, options={})
  @app  = app
  @host = options[:host]
  @server_thread = nil
  @port = options[:port] || Communist.server_port
  @port ||= Communist::Server.ports[@app.object_id]
  @port ||= find_available_port
end

Instance Attribute Details

#appObject (readonly)

Returns the value of attribute app.



35
36
37
# File 'lib/communist/server.rb', line 35

def app
  @app
end

#hostObject (readonly)

Returns the value of attribute host.



35
36
37
# File 'lib/communist/server.rb', line 35

def host
  @host
end

#portObject (readonly)

Returns the value of attribute port.



35
36
37
# File 'lib/communist/server.rb', line 35

def port
  @port
end

Class Method Details

.portsObject



30
31
32
# File 'lib/communist/server.rb', line 30

def ports
  @ports ||= {}
end

.run(&block) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/communist/server.rb', line 97

def self.run(&block)
  app = Sinatra.new do
    set :show_exceptions, true
    set :environment, :test
    disable :protection

    self.class_eval(&block)

    helpers do
      def body(value=nil)
        super
        nil
      end
    end

    after do
      if !response.body.empty?
        content_type :json
        body JSON.generate(response.body)
      end
    end
  end

  new(app).start
end

Instance Method Details

#responsive?Boolean

Returns:

  • (Boolean)


50
51
52
53
54
55
56
57
58
59
60
# File 'lib/communist/server.rb', line 50

def responsive?
  return false if @server_thread && @server_thread.join(0)

  res = Net::HTTP.start(host, @port) { |http| http.get('/__identify__') }

  if res.is_a?(Net::HTTPSuccess) or res.is_a?(Net::HTTPRedirection)
    return res.body == app.object_id.to_s
  end
rescue Errno::ECONNREFUSED, Errno::EBADF
  return false
end

#start(&block) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/communist/server.rb', line 62

def start(&block)
  raise ArgumentError, 'app required' unless app

  unless responsive?
    Communist::Server.ports[app.object_id] = port

    @server_thread = Thread.new do
      Communist.run_default_server(Identify.new(app), port) do |server|
        Communist.servers[app.object_id] = server
      end
    end

    Timeout.timeout(DEFAULT_TIMEOUT) { @server_thread.join(0.1) until responsive? }
  end
rescue TimeoutError
  raise ServerError, "Rack application timed out during start"
else
  self
end

#stopObject

Stops the server after handling the connection. Attempts to stop the server gracefully, otherwise shuts current connection right away.



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/communist/server.rb', line 85

def stop
  server = Communist.servers.delete(app.object_id) { |s| NullServer.new }
  if Communist.server.respond_to?(:shutdown)
    server.shutdown
  elsif Communist.server.respond_to?(:stop!)
    server.stop!
  else
    server.stop
  end
  @server_thread.join
end