Permalink
Browse files

Only use em-http-request on reactor_thread

  This commit makes the SDSClient issue synchronous http requests when
it's running on a different thread from the EventMachine reactor thread.

  - Bumps gem version to 2.0.10

  Test plan:
  - All unit tests passed
  - Deploy CCNG with this change with BOSH and pass lifecycle API BVT's

Change-Id: If9c159901f3f401a1b4474d7eef02899cb44b802
  • Loading branch information...
1 parent 8a970b7 commit b9024a52348223b146ce51126486e88816fa03f4 @d d committed Oct 23, 2012
Showing with 46 additions and 6 deletions.
  1. +4 −4 lib/services/api/clients/sds_client.rb
  2. +40 −0 spec/unit/sds_client_spec.rb
  3. +2 −2 vcap_common.gemspec
View
8 lib/services/api/clients/sds_client.rb
@@ -4,6 +4,7 @@
require 'mime/types'
require 'uri'
+require 'eventmachine'
require 'services/api/const'
require 'services/api/messages'
require 'services/api/multipart'
@@ -23,10 +24,9 @@ class UnexpectedResponse < StandardError; end
def initialize(url, upload_token, timeout=60, opts={})
@url = url
+ # the options hash can't be specified in Ruby if caller omits timeout...
+ raise ArgumentError unless timeout.respond_to?(:to_f)
@timeout = timeout
- @hdrs = {
- 'Content-Type' => 'application/json',
- }
@upload_hdrs = {
'Content-Type' => 'multipart/form-data',
SDS_UPLOAD_TOKEN_HEADER => upload_token
@@ -48,7 +48,7 @@ def perform_multipart_upload(path, file_path)
mime_types = MIME::Types.type_for(file_path) || []
mime_types << "application/octet-stream" if mime_types.empty?
- if EM.reactor_running?
+ if EM.reactor_thread?
payload = {:_method => 'put', :data_file => EM::StreamUploadIO.new(file_path, mime_types[0])}
multipart = EM::Multipart.new(payload, @upload_hdrs)
url = URI.parse(uri.to_s + path)
View
40 spec/unit/sds_client_spec.rb
@@ -58,6 +58,46 @@
MockServer.last_request.headers["HTTP_X_VCAP_SDS_UPLOAD_TOKEN"].should == "secret"
end
+ it "issues a PUT to serialization data server (outside of reactor thread)" do
+ MockServer.stubbed_status = 200
+ MockServer.stubbed_body = "{\"url\": \"http://example.com/foo\"}"
+ port = VCAP::grab_ephemeral_port
+ server = Thin::Server.new("localhost", port, MockServer)
+ server.silent = true
+ Thread.new { server.start }
+
+ f = Tempfile.new("foo")
+ f.write("bar\n")
+ f.close
+
+ client = VCAP::Services::Api::SDSClient.new(
+ "http://localhost:#{port}",
+ "secret",
+ 2,
+ )
+ EM.error_handler do |e|
+ raise e
+ end
+ Timeout.timeout(0.5) do
+ sleep 0.02 until server.running?
+ end
+ server.should be_running
+
+ client.import_from_data(
+ :service => "redis",
+ :service_id => "deadbeef",
+ :msg => f.path,
+ )
+ server.stop
+ Timeout.timeout(0.5) do
+ EM.reactor_thread.join
+ end
+ f.unlink
+ MockServer.last_request.forms["data_file"].should_not be_nil
+ MockServer.last_request.forms["data_file"][:tempfile].read.should == "bar\n"
+ MockServer.last_request.headers["HTTP_X_VCAP_SDS_UPLOAD_TOKEN"].should == "secret"
+ end
+
it "issues a PUT to serialization data server (without EM)" do
MockServer.stubbed_status = 200
MockServer.stubbed_body = "{\"url\": \"http://example.com/foo\"}"
View
4 vcap_common.gemspec
@@ -1,7 +1,7 @@
spec = Gem::Specification.new do |s|
s.name = 'vcap_common'
- s.version = '2.0.9'
- s.date = '2012-09-26'
+ s.version = '2.0.10'
+ s.date = '2012-10-25'
s.summary = 'vcap common'
s.homepage = "http://github.com/vmware-ac/core"
s.description = 'common vcap classes/methods'

0 comments on commit b9024a5

Please sign in to comment.