Skip to content

Commit

Permalink
Use Marshal to serialize minter state rather than YAML.
Browse files Browse the repository at this point in the history
Because performance. See https://gist.github.com/mjgiarlo/1b09f710a625ffb92a8f#file-benchmark-results-with-marshal-serialization. Also provide a rake task for migrating an existing minter state file from YAML to Marshal format.
  • Loading branch information
mjgiarlo committed Aug 5, 2015
1 parent b7fbf6c commit 58aaf5c
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 6 deletions.
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ require 'rspec/core/rake_task'

task default: :spec
RSpec::Core::RakeTask.new

import './lib/tasks/noid_tasks.rake'
8 changes: 8 additions & 0 deletions active_fedora-noid.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "bundler", "~> 1.7"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency 'rspec', '~> 3.2'

spec.post_install_message = <<-END
NOTE: ActiveFedora::Noid 1.0.0 included a change that breaks existing minter
statefiles. Run the `active_fedora:noid:migrate_statefile` rake task to migrate
your statefile. (If you're using a custom statefile, not /tmp/minter-state,, set
an environment variable called AFNOID_STATEFILE with its path.)
END

end
16 changes: 10 additions & 6 deletions lib/active_fedora/noid/synchronized_minter.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
require 'noid'
require 'yaml'

module ActiveFedora
module Noid
class SynchronizedMinter
Expand Down Expand Up @@ -34,16 +32,22 @@ def default_statefile
@statefile ||= ActiveFedora::Noid.config.statefile
end

def state_for(io_object)
Marshal.load(io_object.read)
rescue TypeError, ArgumentError
{ template: template }
end

def next_id
id = ''
::File.open(statefile, ::File::RDWR|::File::CREAT, 0644) do |f|
f.flock(::File::LOCK_EX)
yaml = ::YAML::load(f.read) || { template: template }
minter = ::Noid::Minter.new(yaml)
state = state_for(f)
minter = ::Noid::Minter.new(state)
id = minter.mint
f.rewind
yaml = ::YAML::dump(minter.dump)
f.write yaml
new_state = Marshal.dump(minter.dump)
f.write(new_state)
f.flush
f.truncate(f.pos)
end
Expand Down
29 changes: 29 additions & 0 deletions lib/tasks/noid_tasks.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require 'active_fedora/noid'
require 'noid'
require 'yaml'

namespace :active_fedora do
namespace :noid do
desc 'Migrate minter state file from YAML to Marshal'
task :migrate_statefile do
statefile = ENV.fetch('AFNOID_STATEFILE', ActiveFedora::Noid.config.statefile)
raise "File not found: #{statefile}\nAborting" unless File.exist?(statefile)
puts "Migrating #{statefile} from YAML to Marshal serialization..."
File.open(statefile, File::RDWR | File::CREAT, 0644) do |f|
f.flock(File::LOCK_EX)
begin
yaml_state = YAML.load(f)
rescue Psych::SyntaxError
raise "File not valid YAML: #{statefile}\nAborting."
end
minter = Noid::Minter.new(yaml_state)
f.rewind
new_state = Marshal.dump(minter.dump)
f.write(new_state)
f.flush
f.truncate(f.pos)
end
puts "Done!"
end
end
end

0 comments on commit 58aaf5c

Please # to comment.