Skip to content

Instantly share code, notes, and snippets.

@dreverri
Created September 1, 2012 21:58
Show Gist options
  • Save dreverri/3588757 to your computer and use it in GitHub Desktop.
Save dreverri/3588757 to your computer and use it in GitHub Desktop.

Issue 1

When saving an object with siblings Ripple saved the object with Content-Type set to multipart/mixed.

This has been fixed in v1.0.0beta2 by requiring Ripple documents to specify an on_conflict handler.

Steps to Reproduce

cd bad_content_type
bundle install
bundle exec ruby foo.rb

Issue 2

Accessing objects incorrectly created by Ripple results in an exception being raised related to an unimplemented serializer.

Steps to Reproduce

cd handling_bad_content_type
bundle install
bundle exec ruby scenario1.rb

Issue 3

Accessing objects incorrectly created by Ripple results in an exception being raised related to parsing a multipart message with a nil boundary.

Steps to Reproduce

cd handling_bad_content_type
bundle install
bundle exec ruby scenario2.rb
---
BUNDLE_PATH: vendor/bundle
BUNDLE_DISABLE_SHARED_GEMS: '1'
---
BUNDLE_PATH: vendor/bundle
BUNDLE_DISABLE_SHARED_GEMS: '1'
require 'bundler/setup'
require 'ripple'
class Foo
include Ripple::Document
property :bar, String
end
Foo.bucket.allow_mult = true
foo = Foo.new()
foo.bar = "0"
foo.save!
foo1 = Foo.find(foo.key)
foo1.bar = "1"
foo2 = Foo.find(foo.key)
foo2.bar = "2"
foo1.save!
foo2.save!
foo3 = Foo.find(foo.key)
foo3.save!
# BOOM!!!!!!!!!!!
Foo.find(foo.key)
source 'https://rubygems.org'
gem 'ripple', "0.9.5"
source 'https://rubygems.org'
gem 'ripple', :git => "git://github.com/seancribbs/ripple.git", :tag => "v1.0.0.beta2"
require 'bundler/setup'
require 'ripple'
class Foo
include Ripple::Document
property :bar, String
on_conflict { record = self }
end
Foo.bucket.allow_mult = true
# Scenario 1
# Use ruby-riak-client to create broken object
foo = Foo.bucket.new()
foo.raw_data = "{\"bar\":null,\"_type\":\"Foo\"}"
foo.content_type = "multipart/mixed"
foo.store
# BOOM!!!!!!!!!!!
Foo.find(foo.key)
# Fix
Riak::Serializers['multipart/mixed'] = Riak::Serializers::ApplicationJSON
require 'bundler/setup'
require 'ripple'
class Foo
include Ripple::Document
property :bar, String
on_conflict { record = self }
end
Foo.bucket.allow_mult = true
# Scenario 2
# Use ruby-riak-client to create broken object
foo = Foo.bucket.new()
foo.raw_data = "{\"bar\":null,\"_type\":\"Foo\"}"
foo.content_type = "multipart/mixed"
foo.store
foo1 = Foo.bucket.get(foo.key)
foo2 = Foo.bucket.get(foo.key)
foo1.raw_data = "{\"bar\":null,\"_type\":\"Foo\"}"
foo1.content_type = "multipart/mixed"
foo1.store
foo2.raw_data = "{\"bar\":null,\"_type\":\"Foo\"}"
foo2.content_type = "application/json"
foo2.store
# BOOM!!!!!!!!!!!
Foo.find(foo.key)
# Fix
Riak::Serializers['multipart/mixed'] = Riak::Serializers::ApplicationJSON
module Riak
module Util
module Multipart
def parse_multipart_section(part)
headers = Headers.new
if md = part.match(/\r?\n\r?\n/)
body = md.post_match
md.pre_match.split(/\r?\n/).each do |line|
headers.parse(line)
end
if headers["content-type"] =~ /multipart\/mixed/
boundary = extract_boundary(headers.to_hash["content-type"].first)
if boundary.nil?
# can't handle multipart/mixed without a boundary
# let the application potentially handle
# e.g. Riak::Serializers['multipart/mixed'] = Riak::Serializers::ApplicationJSON
{:headers => headers.to_hash, :body => body}
else
parse(body, boundary)
end
else
{:headers => headers.to_hash, :body => body}
end
end
end
end
end
end
@myronmarston
Copy link

Hey @dreverri, thanks for putting this together!

This has been fixed in v1.0.0beta2 by requiring Ripple documents to specify an on_conflict handler.

Two questions/comments about this:

  • I'm the author of ripple's on_conflict hook (it was extracted from our code base, actually) and I was curious to see the change you refer to here. I looked through the recent commit history of ripple and couldn't find anything like this. For reference, we've never used the 0.9.5 release of ripple in production; in fact we've been locked to my last ripple commit or newer for the last nine months (I updated our code base to that commit the day I added it to ripple, IIRC).
  • We've always had an on_conflict handler for all documents that have allow_mult = true, so I don't see how this explains what happened. Silo's been properly resolving conflicted documents for 12+ months.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment