Class: Twirl::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/twirl/server.rb

Constant Summary collapse

ConfigTemplate =
<<_EOC
import com.twitter.conversions.storage._
import com.twitter.conversions.time._
import com.twitter.logging.config._
import com.twitter.ostrich.admin.config._
import net.lag.kestrel.config._

new KestrelConfig {
  listenAddress = "0.0.0.0"
  memcacheListenPort = <%= @memcache_port %>
  textListenPort = <%= @text_port %>
  thriftListenPort = <%= @thrift_port %>

  queuePath = "<%= @queue_path %>"

  clientTimeout = 30.seconds

  expirationTimerFrequency = 1.second

  maxOpenTransactions = 100

  default.defaultJournalSize = 16.megabytes
  default.maxMemorySize = 128.megabytes
  default.maxJournalSize = 1.gigabyte

  admin.httpPort = <%= @admin_port %>

  admin.statsNodes = new StatsConfig {
    reporters = new TimeSeriesCollectorConfig
  }

  loggers = new LoggerConfig {
    level = Level.DEBUG
    handlers = new FileHandlerConfig {
      filename = "<%= @log_file %>"
      roll = Policy.Never
    }
  }
}
_EOC

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Server.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/twirl/server.rb', line 65

def initialize(dir, options = {})
  @dir           = dir

  @version       = options.fetch(:version)       { "2.4.1" }
  @memcache_port = options.fetch(:memcache_port) { 22133 }
  @thrift_port   = options.fetch(:thrift_port)   { 2229 }
  @text_port     = options.fetch(:text_port)     { 2222 }
  @admin_port    = options.fetch(:admin_port)    { 2223 }

  @download_dir  = options.fetch(:download_dir)  { "/tmp" }
  @stage         = options.fetch(:stage)         { "twirl" }

  @remote_zip    = "http://robey.github.io/kestrel/download/kestrel-#{@version}.zip"
  @zip_file      = File.join(@download_dir, "kestrel-#{@version}.zip")
  @unzipped_file = File.join(@download_dir, "kestrel-#{@version}")
  @jar_file      = File.join(@unzipped_file, "kestrel_2.9.2-#{@version}.jar")

  @queue_path  = File.join(@dir, "data")
  @log_path    = File.join(@dir, "logs")
  @config_path = File.join(@dir, "config")

  @log_file    = File.join(@log_path, "kestrel.log")
  @config_file = File.join(@config_path, "#{@stage}.scala")
end

Instance Attribute Details

#admin_portObject (readonly)

Public: The admin_port kestrel will run on.



63
64
65
# File 'lib/twirl/server.rb', line 63

def admin_port
  @admin_port
end

#memcache_portObject (readonly)

Public: The memcache_port kestrel will run on.



54
55
56
# File 'lib/twirl/server.rb', line 54

def memcache_port
  @memcache_port
end

#text_portObject (readonly)

Public: The text_port kestrel will run on.



60
61
62
# File 'lib/twirl/server.rb', line 60

def text_port
  @text_port
end

#thrift_portObject (readonly)

Public: The thrift_port kestrel will run on.



57
58
59
# File 'lib/twirl/server.rb', line 57

def thrift_port
  @thrift_port
end

#versionObject (readonly)

Public: The version kestrel will run.



51
52
53
# File 'lib/twirl/server.rb', line 51

def version
  @version
end

Instance Method Details

#downloadObject

Private: Downloads the file.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/twirl/server.rb', line 115

def download
  uri = URI(@remote_zip)

  Net::HTTP.start(uri.host, uri.port) do |http|
    request = Net::HTTP::Get.new uri.path

    http.request request do |response|
      if response.code.to_i == 200
        downloaded = 0
        last_percent = 0
        total = response["content-length"].to_i
        puts "Downloading #{total} bytes to #{@zip_file}"

        File.open @zip_file, "w" do |io|
          response.read_body do |chunk|
            io.write chunk
            downloaded += chunk.size
            percent_complete = ((downloaded.to_f / total) * 100).round
            show_status = percent_complete % 5 == 0 && last_percent != percent_complete

            if show_status
              last_percent = percent_complete
              puts "#{downloaded}/#{total}\t#{percent_complete}%"
            end
          end
        end
      else
        abort "Could not downloaded kestrel from #{@remote_zip} #{response.inspect}"
      end
    end
  end
end

#downloaded?Boolean

Private: Returns true or false depending on whether the file has been downloaded.

Returns:

  • (Boolean)


110
111
112
# File 'lib/twirl/server.rb', line 110

def downloaded?
  File.exists?(@zip_file)
end

#ensure_configuredObject

Private: Ensure directories and configuration files are ready to go.



169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/twirl/server.rb', line 169

def ensure_configured
  [
    @queue_path,
    @log_path,
    @config_path,
  ].each do |path|
    FileUtils.mkdir_p path
  end

  config_contents = ERB.new(ConfigTemplate).result(binding)
  File.write @config_file, config_contents
end

#ensure_downloadedObject

Private: Downloads the file if it has not been downloaded.



104
105
106
# File 'lib/twirl/server.rb', line 104

def ensure_downloaded
  download unless downloaded?
end

#ensure_unzippedObject

Private: Ensures that file is unzipped if downloaded.



149
150
151
152
153
# File 'lib/twirl/server.rb', line 149

def ensure_unzipped
  if downloaded? && !unzipped?
    unzip
  end
end

#get_response(path) ⇒ Object

Private: Allows requesting things from the kestrel admin.



245
246
247
248
249
250
251
# File 'lib/twirl/server.rb', line 245

def get_response(path)
  uri = URI.parse("http://localhost:#{@admin_port}/#{path}")
  response = Net::HTTP.get_response(uri)
  JSON.parse(response.body)
rescue => exception
  {}
end

#pingObject

Private: Pings the kestrel server.



231
232
233
# File 'lib/twirl/server.rb', line 231

def ping
  get_response("ping")["response"]
end

#running?Boolean

Private: Returns true if server is running else false.

Returns:

  • (Boolean)


207
208
209
210
211
212
# File 'lib/twirl/server.rb', line 207

def running?
  return "pong" == ping
rescue => exception
  $stderr.puts exception.inspect
  false
end

#shutdownObject

Private: Shutsdown the kestrel server.



236
237
238
239
240
241
242
# File 'lib/twirl/server.rb', line 236

def shutdown
  h = get_response("shutdown")
  return h["response"] == "ok"
rescue => exception
  puts "Failed to shutdown: #{exception.inspect}"
  false
end

#startObject

Public: Downloads, unzips and starts the server.



91
92
93
94
95
96
# File 'lib/twirl/server.rb', line 91

def start
  ensure_downloaded
  ensure_unzipped
  ensure_configured
  start_server
end

#start_serverObject

Private: Starts the server. Assumes downloaded and unzipped



183
184
185
186
187
188
189
190
191
192
193
# File 'lib/twirl/server.rb', line 183

def start_server
  puts "Starting server."
  Dir.chdir(@dir) do
    system "java -jar #{@jar_file} -f #{@config_file} &"

    loop do
      break if running?
    end
  end
  puts "Started server."
end

#statusObject

Private: Prints out the status of the server.



220
221
222
223
224
225
226
227
228
# File 'lib/twirl/server.rb', line 220

def status
  if running?
    :running
  else
    :stopped
  end
rescue => exception
  :unknown
end

#stopObject

Public: Stops the server.



99
100
101
# File 'lib/twirl/server.rb', line 99

def stop
  stop_server
end

#stop_serverObject

Private: Stops the server.



196
197
198
199
200
201
202
203
204
# File 'lib/twirl/server.rb', line 196

def stop_server
  puts "Stopping server."
  shutdown

  loop do
    break if stopped?
  end
  puts "Stopped server."
end

#stopped?Boolean

Private: Returns true if server is stopped else false.

Returns:

  • (Boolean)


215
216
217
# File 'lib/twirl/server.rb', line 215

def stopped?
  return !running?
end

#unzipObject

Private: Unzips the file.



156
157
158
159
160
# File 'lib/twirl/server.rb', line 156

def unzip
  Dir.chdir(File.dirname(@zip_file)) do
    system "unzip", "-o", @zip_file
  end
end

#unzipped?Boolean

Private: Returns true or false depending on whether the file has been unzipped.

Returns:

  • (Boolean)


164
165
166
# File 'lib/twirl/server.rb', line 164

def unzipped?
  File.exists?(@unzipped_file)
end