ruby-rdf / rdf

RDF.rb is a pure-Ruby library for working with Resource Description Framework (RDF) data.
http://rubygems.org/gems/rdf
The Unlicense
382 stars 92 forks source link

Frozen error accessing URI #388

Closed jcoyne closed 6 years ago

jcoyne commented 6 years ago

I suspect this is a thread safety issue.

My code is doing something like this:

SWS_GEONAMES = RDF::Vocabulary.new('http://sws.geonames.org/')

# in separate threads:
countries.each do |geocode_id|
  puts Rialto::Etl::Vocabs::SWS_GEONAMES["#{geocode_id}/"]
end
Exception: FrozenError: can't modify frozen #<Class:#<RDF::URI:0x00007fbe20700e28>>
        11: from /opt/app/vitro/.rvm/gems/ruby-2.5.1@rialto/gems/traject-3.0.0/lib/traject/translation_map.rb:133:in `eval'
        10: from lib/translation_maps/geocodes_to_country_names.rb:10:in `block in _lookup!'
         9: from /opt/app/vitro/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/csv.rb:1141:in `foreach'
         8: from /opt/app/vitro/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/csv.rb:1289:in `open'
         7: from /opt/app/vitro/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/csv.rb:1142:in `block in foreach'
         6: from /opt/app/vitro/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/csv.rb:1764:in `each'
         5: from lib/translation_maps/geocodes_to_country_names.rb:13:in `block (2 levels) in _lookup!'
         4: from /opt/app/vitro/.rvm/gems/ruby-2.5.1@rialto/gems/rdf-3.0.5/lib/rdf/vocabulary.rb:642:in `[]'
         3: from /opt/app/vitro/.rvm/gems/ruby-2.5.1@rialto/gems/rdf-3.0.5/lib/rdf/vocabulary.rb:877:in `intern'
         2: from /opt/app/vitro/.rvm/gems/ruby-2.5.1@rialto/gems/rdf-3.0.5/lib/rdf/model/uri.rb:669:in `freeze'
         1: from /opt/app/vitro/.rvm/gems/ruby-2.5.1@rialto/gems/rdf-3.0.5/lib/rdf/model/uri.rb:1108:in `authority'
/opt/app/vitro/.rvm/gems/ruby-2.5.1@rialto/gems/rdf-3.0.5/lib/rdf/model/uri.rb:823:in `object': can't modify frozen #<Class:#<RDF::URI:0x00007fbe20700e28>>

I am unable to duplicate this error in a single thread context.

gkellogg commented 6 years ago

@jcoyne I created a mutex and use it to synchronize code in URI#freeze. Care to see if that helps?

jcoyne commented 6 years ago

@gkellogg I'm testing it now. Thanks.

jcoyne commented 6 years ago

@gkellogg I ran this code for the last 6 hours and no further problems arose. Thanks!

gkellogg commented 6 years ago

Great, I can't think of other classes that might need this, but now we know how to handle it.