views:

108

answers:

1

I'm trying to use the KirbyBase (in Ruby) in server/client mode and having some problems... Here's the setup (I'm working with a speacilized embedded linux system (explained at the bottom of post) but; I'll call those PC for the arguments sake)

  • 2 PCs using an NFS mounted NAS drive on network (mounted on /mnt/sharedSpace), one will be server and the other client...
  • I have 2 previously created tables named 'history.tbl' and 'registeredTags.tbl' in /mnt/sharedSpace/data

Here's the server code:

# Multi-user server script for KirbyBase.

require 'DatabaseObjects.rb'
include DatabaseObjects
require 'kirbybase'
require 'drb'

puts 'Initializing database server and indexes...'

# Create an instance of the database.
db = KirbyBase.new(:server,nil,nil,'/mnt/sharedSpace/data/')

DRb.start_service('druby://:44444', db)

puts 'Server ready to receive connections...'

DRb.thread.join

And below is the client code:

#draft.rb
require 'kirbybase'
require 'DatabaseObjects.rb'
require 'drb'
include DatabaseObjects
begin
    db = KirbyBase.new(:client, '192.168.1.11', 44444)
    if db.table_exists?(:registeredTags)
        puts "found table"
        registeredTagsTable = db.get_table(:registeredTags)
        puts "got table"
        puts registeredTagsTable.select().to_report
    else
        puts "couldnt found table"
    end
rescue Exception => sp
    puts sp.message
    puts sp.backtrace.inspect
end

I start the server and it prints 'Server ready..........' then I start the client code on the other machine and here's what I get:

undefined method `close' for nil:NilClass
["(druby://192.168.1.11:44444) /usr/lib/ruby/1.8/kirbybase.rb:1765:in `with_table'", "(druby://192.168.1.11:44444) /usr/lib/ruby/1.8/kirbybase.rb:992:in `get_header_vars'", "/usr/lib/ruby/1.8/kirbybase.rb:3112:in `update_header_vars'", "/usr/lib/ruby/1.8/kirbybase.rb:2026:in `initialize'", "/usr/lib/ruby/1.8/kirbybase.rb:2002:in `new'", "/usr/lib/ruby/1.8/kirbybase.rb:2002:in `create_called_from_database_instance'", "/usr/lib/ruby/1.8/kirbybase.rb:463:in `initialize'", "/usr/lib/ruby/1.8/kirbybase.rb:461:in `each'", "/usr/lib/ruby/1.8/kirbybase.rb:461:in `initialize'", "draft.rb:6:in `new'", "draft.rb:6"]

But; if I start the same client code on the same machine as the server code is running on, everything goes smoothly and it prints the table contents. Any ideas...?

System explanation as requested by some: The device I'm working with is an intelligent RFID reader, with an embedded linux arm based computer on-board. The only api/language manufacturer allows and provides (w/o getting out of license terms) is ruby, and they give no-support for installing extra-stuff and they have customized the kernel in device to make installing/compiling anything as hard as possible. I can use extra ruby stuff if they're just .rb lib files that is I can easily just include them in my code, but anything that requires compiling is a no-no. Also, this system does not have gem.

Edit2: Respond for first answer, I have changed the said function as following:

def with_table(table, access='r')
    begin
        yield fptr = open(table.filename, access)
    ensure
        if !fptr.nil? then
       fptr.close
      end
    end
end

And now I'm getting this error:

druby://localhost.localdomain:1027 - #<Errno::ECONNREFUSED: Connection refused - connect(2)>
["(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/drb/drb.rb:736:in `open'", "(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/drb/drb.rb:729:in `each'", "(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/drb/drb.rb:729:in `open'", "(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/drb/drb.rb:1196:in `initialize'", "(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/drb/drb.rb:1176:in `new'", "(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/drb/drb.rb:1176:in `open'", "(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/drb/drb.rb:1092:in `method_missing'", "(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/drb/drb.rb:1110:in `with_friend'", "(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/drb/drb.rb:1091:in `method_missing'", "(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/kirbybase.rb:1763:in `with_table'", "(druby://192.168.1.22:44444) /usr/lib/ruby/1.8/kirbybase.rb:992:in `get_header_vars'", "/usr/lib/ruby/1.8/kirbybase.rb:3114:in `update_header_vars'", "/usr/lib/ruby/1.8/kirbybase.rb:2028:in `initialize'", "/usr/lib/ruby/1.8/kirbybase.rb:2004:in `new'", "/usr/lib/ruby/1.8/kirbybase.rb:2004:in `create_called_from_database_instance'", "/usr/lib/ruby/1.8/kirbybase.rb:463:in `initialize'", "/usr/lib/ruby/1.8/kirbybase.rb:461:in `each'", "/usr/lib/ruby/1.8/kirbybase.rb:461:in `initialize'", "draft.rb:6:in `new'", "draft.rb:6"]
+1  A: 

Inside KirbyBase.new() see with_table

def with_table(table, access='r')
    begin
        yield fptr = open(table.filename, access)
    ensure
        fptr.close
    end
end

What's happening, I think, is that the open() is returning nil, and then the associated block at the with_table call site is getting a nil fptr and trying to deref nil inside get_header_vars. The subsequent exception then unwinds back to with_table, which then tries to deref fptr again, to call close, producing an unrescued and final exception.

Now, I say open() returns nil, not open() fails, because (see open(Kernel)) when the path is a pipeline, the child always returns nil and the parent is supposed to ignore it. So, the next thing to do is to start debugging the internals of KirbyBase and find out if its your issue or a KirbyBase issue. I hope I've helped get you started.

One way to debug this is by monkeypatching KirbyBase. If you want your own copy of the source to read, on a development host that does have gem do something like:

gem fetch KirbyBase
mkdir t
gem unpack --target=t/. KirbyBase*
DigitalRoss
digitalross, please see the second edit on original question for a respond.
kramer