view · edit · sidebar · attach · print · history

30-12-2011

YAML.dump error

ch.oddb> ODBA.cache.fetch('508').class
-> ODDB::Company
ch.oddb> YAML.dump(ODBA.cache.fetch('508'))
-> connection closed

Test (src/util/oddbapp.rb)

module ODDB
  class App < SBSM::DRbServer
...
p ODBA.cache.fetch('508').to_yaml
...

Error

/usr/local/lib/ruby/gems/1.9.1/gems/dbd-pg-0.3.9/lib/dbd/pg/database.rb:228: stack level too deep (SystemStackError)

Test (sample.rb)

require 'yaml'

class Test
  attr_accessor :child
end

test1 = Test.new
test = test1
2000.times do
  test.child = Test.new
  test = test.child
end

puts test1.to_yaml

/usr/local/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb

      def accept target
@stack_level ||= 0
p "getin YAMLTree#accept stack_level: #{@stack_level += 1}"
...
        end
@stack_level-=1
      end

Result

...
"getin Psych::Visitors::YAMLTree#accept stack_level: 1393"
/usr/local/lib/ruby/1.9.1/psych/tree_builder.rb:75: stack level too deep (SystemStackError)

Note

  • It works until 1392 stack level
  • The stack size is possible to be changed with RUBY_VM_THREAD_STACK_SIZE in vm_core.c
  • Default size is 128KB (This is constant)
  • But this stack size does not help this YAML.dump error

Test (/usr/local/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb)

      def accept target
@stack_level ||= 0
if target.odba_id
  puts " "*@stack_level + "#{@stack_level+=1}, #{target.class}(#{target.odba_id})"
else
  puts " "*@stack_level + "#{@stack_level+=1}, #{target.class}"
end
...
@stack_level-=1
      end

Run

ch.oddb> ODBA.cache.fetch('508').to_yaml

Result

Note

  • Objects are parsed recursively
  • Company -> Registration -> Company, Indication -> Registration -> Company, Indication -> ...

Experiment (/usr/local/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb)

      def visit_Array o
        register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK)
        #o.each { |c| accept c }
        o.each { |c|
          accept c unless c.is_a?(ODDB::Registration)
        }
        @emitter.end_sequence
      end

Result

Experiment (syck)

  • src/util/oddbapp.rb
 require 'yaml'
 YAML::ENGINE.yamler='syck' 

Run

ch.oddb> open("/home/masa/work/syck.dat", "w"){|out| out.puts ODBA.cache.fetch('508').to_yaml}

Result

From Redmine and Syck vs Psych

view · edit · sidebar · attach · print · history
Page last modified on December 31, 2011, at 10:42 AM