Permalink
Browse files

custom serialization/deserialization methods for any class instead ju…

…st hardcoded AR
  • Loading branch information...
1 parent 3a09556 commit 8585312637b828a5f5b4574764d570701f7dc70a @elado committed Aug 18, 2012
@@ -21,11 +21,28 @@ def perform(*msg)
end
module ActiveRecord
- def delay
- Proxy.new(DelayedModel, self)
+ module ClassMethods
+ def sidekiq_deserialize(string)
+ where(id: string.to_i).first
+ end
end
- def delay_for(interval)
- Proxy.new(DelayedModel, self, Time.now.to_f + interval.to_f)
+
+ module InstanceMethods
+ def delay
+ Proxy.new(DelayedModel, self)
+ end
+ def delay_for(interval)
+ Proxy.new(DelayedModel, self, Time.now.to_f + interval.to_f)
+ end
+
+ def sidekiq_serialize
+ "SIDEKIQ:AR@#{self.class.name}@#{self.id}"
+ end
+ end
+
+ def self.included(receiver)
+ receiver.extend ClassMethods
+ receiver.send :include, InstanceMethods
end
end
@@ -2,31 +2,32 @@ module Sidekiq
module Extensions
class ArgsSerializer
# inspired by DelayedJob
- CLASS_STRING_FORMAT = /^CLASS\:([A-Z][\w\:]+)$/
- AR_STRING_FORMAT = /^AR\:([A-Z][\w\:]+)\:(\d+)$/
- YAML_STRING_FORMAT = /\A---/
+ SIDEKIQ_CUSTOM_SERIALIZATION_FORMAT = /\ASIDEKIQ\:(?:\w+)@(.+)/
def self.serialize(obj)
- case obj
- when Array then obj.map { |o| serialize(o) }
- when Hash then obj.inject({}) { |memo, (k, v)| memo[k] = serialize(v); memo }
- when ::ActiveRecord::Base then "AR:#{obj.class.name}:#{obj.id}"
- when Class, Module then "CLASS:#{obj.name}"
- else obj.to_yaml
+ if obj.respond_to?(:sidekiq_serialize)
+ obj.sidekiq_serialize
+ else
+ case obj
+ when Array then obj.map { |o| serialize(o) }
+ when Hash then obj.inject({}) { |memo, (k, v)| memo[k] = serialize(v); memo }
+ else obj.to_yaml
+ end
end
end
def self.deserialize(obj)
case obj
- when CLASS_STRING_FORMAT then $1.constantize
- when AR_STRING_FORMAT then $1.constantize.where(id: $2).first
- when Array then obj.map { |item| deserialize(item) }
- when Hash then obj.inject({}) { |memo, (k, v)| memo[k] = deserialize(v); memo }
- else YAML.load(obj)
+ when SIDEKIQ_CUSTOM_SERIALIZATION_FORMAT
+ klass_name, args = $1.split('@')
+ klass = klass_name.constantize
+ klass.respond_to?(:sidekiq_deserialize) && args ? klass.sidekiq_deserialize(args) : klass
+ when Array then obj.map { |item| deserialize(item) }
+ when Hash then obj.inject({}) { |memo, (k, v)| memo[k] = deserialize(v); memo }
+ else YAML.load(obj)
end
end
-
def self.serialize_message(target, method_name, *args)
[ serialize(target), method_name, serialize(args) ]
end
@@ -25,9 +25,14 @@ def delay
def delay_for(interval)
Proxy.new(DelayedClass, self, Time.now.to_f + interval.to_f)
end
+
+ def sidekiq_serialize
+ "SIDEKIQ:CLASS@#{self.name}"
+ end
end
end
end
Class.send(:include, Sidekiq::Extensions::Klass)
+Module.send(:include, Sidekiq::Extensions::Klass)
@@ -2,6 +2,9 @@
require 'sidekiq'
require 'active_record'
require 'action_mailer'
+require 'sidekiq/rails'
+
+Sidekiq.hook_rails!
class TestArgsSerializer < MiniTest::Unit::TestCase
describe 'args parser' do
@@ -21,13 +24,13 @@ class User < ActiveRecord::Base
end
it 'serializes active record class' do
- assert_equal "CLASS:TestArgsSerializer::User", ser(User)
+ assert_equal "SIDEKIQ:CLASS@TestArgsSerializer::User", ser(User)
assert_equal TestArgsSerializer::User, deser(ser(User))
end
it 'serializes active record instance' do
user = User.create!
- assert_equal "AR:TestArgsSerializer::User:#{user.id}", ser(user)
+ assert_equal "SIDEKIQ:AR@TestArgsSerializer::User@#{user.id}", ser(user)
assert_equal user, deser(ser(user))
end
@@ -38,12 +41,12 @@ module SomeModule
end
it 'serializes class' do
- assert_equal "CLASS:TestArgsSerializer::SomeClass", ser(SomeClass)
+ assert_equal "SIDEKIQ:CLASS@TestArgsSerializer::SomeClass", ser(SomeClass)
assert_equal SomeClass, deser(ser(SomeClass))
end
it 'serializes module' do
- assert_equal "CLASS:TestArgsSerializer::SomeModule", ser(SomeModule)
+ assert_equal "SIDEKIQ:CLASS@TestArgsSerializer::SomeModule", ser(SomeModule)
assert_equal SomeModule, deser(ser(SomeModule))
end
@@ -1,5 +1,6 @@
require 'helper'
require 'sidekiq'
+require 'fileutils'
require 'active_record'
require 'action_mailer'
require 'sidekiq/extensions/action_mailer'

0 comments on commit 8585312

Please sign in to comment.