Class: Mrt::Ingest::OneTimeServer

Inherits:
Object
  • Object
show all
Defined in:
lib/mrt/ingest/one_time_server.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeOneTimeServer

Returns a new instance of OneTimeServer.



28
29
30
31
32
33
34
35
36
37
# File 'lib/mrt/ingest/one_time_server.rb', line 28

def initialize
  @dir = Dir.mktmpdir
  @mutex = Mutex.new
  @known_paths = {}
  @requested = {}
  @port = get_open_port
  @file_callback = ->(req, _res) { @requested[req.path] ||= true }
  @server = WEBrick::HTTPServer.new(Port: @port)
  @server.mount('/', WEBrick::HTTPServlet::FileHandler, @dir, FileCallback: @file_callback)
end

Instance Attribute Details

#dirObject (readonly)

Returns the value of attribute dir.



11
12
13
# File 'lib/mrt/ingest/one_time_server.rb', line 11

def dir
  @dir
end

#portObject (readonly)

Returns the value of attribute port.



11
12
13
# File 'lib/mrt/ingest/one_time_server.rb', line 11

def port
  @port
end

Instance Method Details

#add_file(sourcefile = nil) ⇒ Object

Add a file to this server. Returns the URL to use to fetch the file & the file path



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/mrt/ingest/one_time_server.rb', line 65

def add_file(sourcefile = nil)
  fullpath = temppath
  path = File.basename(fullpath)

  if sourcefile
    @server.mount("/#{path}", WEBrick::HTTPServlet::FileHandler, sourcefile.path, FileCallback: @file_callback)
  else
    File.open(fullpath, 'w+') { |f| yield f }
  end
  ["http://#{Socket.gethostname}:#{@port}/#{path}", fullpath]
end

#finished?Boolean

Return true if each file has been served.

Returns:

  • (Boolean)


40
41
42
43
44
45
46
# File 'lib/mrt/ingest/one_time_server.rb', line 40

def finished?
  Dir.entries(@dir).each do |entry|
    next if %w[. ..].include?(entry)
    return false if @requested["/#{entry}"].nil?
  end
  true
end

#get_open_port(start = 8081) ⇒ Object

Find an open port, starting with start and adding one until we get an open port



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/mrt/ingest/one_time_server.rb', line 15

def get_open_port(start = 8081)
  try_port = start
  loop do
    begin
      s = TCPServer.open(try_port)
      s.close
      return try_port
    rescue Errno::EADDRINUSE
      try_port += 1
    end
  end
end

#join_serverObject

Wait for server to finish serving all files.



94
95
96
97
98
99
# File 'lib/mrt/ingest/one_time_server.rb', line 94

def join_server
  # ensure that each file is requested once before shutting down
  sleep(1) until finished?
  @server.shutdown
  @thread.join
end

#runObject

Run the server and wait until each file has been served once. Cleans up files before it returns.



103
104
105
106
107
108
# File 'lib/mrt/ingest/one_time_server.rb', line 103

def run
  start_server
  join_server
  #    FileUtils.rm_rf(@dir)
  nil
end

#start_serverObject



77
78
79
80
81
82
83
84
85
# File 'lib/mrt/ingest/one_time_server.rb', line 77

def start_server
  if @thread.nil?
    @thread = Thread.new do
      @server.start
    end
  end
  sleep(0.1) while @server.status != :Running
  @thread
end

#stop_serverObject

Stop server unconditionally.



88
89
90
91
# File 'lib/mrt/ingest/one_time_server.rb', line 88

def stop_server
  @server.shutdown
  @thread.join
end

#temppathObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/mrt/ingest/one_time_server.rb', line 48

def temppath
  tmpfile = Tempfile.new('tmp', @dir)
  tmppath = tmpfile.path
  tmpfile.close!
  @mutex.synchronize do
    unless @known_paths.key?(tmppath)
      # no collision
      @known_paths[tmppath] = true
      return tmppath
    end
  end
  # need to retry, there was a collision
  temppath
end