XMLRPC and complex data structures

Hi all,

Ruby 1.6.7, REXML 2.4.2, Sys/ProcTable 3.1, XML-RPC 1.7.11

I’m getting the dreaded “Internal Server Error” when I try to return an
array of structs within a handler.

Here’s the code:

require “xmlrpc/server”
require “sys/proctable”
include Sys

class Test
def add(a,b)
a + b
end

def ps
a =
a = ProcTable.ps # This fails
#ProcTable.ps{|struct| a.push(struct.pid)} # This works
return a
end
end

server = XMLRPC::Server.new(8889,“1.2.3.4”,4,$stdout) # Use a real IP
server.add_handler(“test”,Test.new)
server.serve

The ProcTable.ps call returns an array of structs in lvalue context, and
that seems to be the problem. I also tried just returning a list of
pid’s and that worked fine. The “add” method also works fine (I just
threw that in for testing purposes).

Here’s the actual client code:

require “xmlrpc/client”

client = XMLRPC::Client.new(“1.2.3.4”,nil,8889) # Use a real IP

begin
v = client.call(“test.ps”)
rescue RuntimeError => e
puts “Error:”
puts e.faultCode
puts e.faultString
rescue XMLRPC::FaultException => e
puts “Error:”
puts e.faultCode
puts e.faultString
end

Here’s the RuntimeError message:

ruby xmlrpcClientTest.rb
Error:
xmlrpcClientTest.rb:9: undefined method `faultCode’ for
#RuntimeError:0x15bb30 (NameError)

Any ideas?

Regards,

Dan

Hi all,

Ruby 1.6.7, REXML 2.4.2, Sys/ProcTable 3.1, XML-RPC 1.7.11

I’m getting the dreaded “Internal Server Error” when I try to return an
array of structs within a handler.

Here’s the code:

require “xmlrpc/server”
require “sys/proctable”
include Sys

class Test
def add(a,b)
a + b
end

def ps
a =
a = ProcTable.ps # This fails
#ProcTable.ps{|struct| a.push(struct.pid)} # This works
return a
end
end

server = XMLRPC::Server.new(8889,“1.2.3.4”,4,$stdout) # Use a real IP
server.add_handler(“test”,Test.new)
server.serve

Is ProcTable.ps really of type “Struct”? Or is it an object of an
user-defined class?

Does ProcTable.ps return nil under some circumstances.

If that doesn’t help, please send me the definition of ProcTable.ps.

The ProcTable.ps call returns an array of structs in lvalue context, and
that seems to be the problem. I also tried just returning a list of
pid’s and that worked fine. The “add” method also works fine (I just
threw that in for testing purposes).

Here’s the actual client code:

require “xmlrpc/client”

client = XMLRPC::Client.new(“1.2.3.4”,nil,8889) # Use a real IP

begin
v = client.call(“test.ps”)
rescue RuntimeError => e
puts “Error:”
puts e.faultCode
puts e.faultString
rescue XMLRPC::FaultException => e

Should be:

rescue XMLRPC::FaultStructure => e

puts “Error:”
puts e.faultCode
puts e.faultString
end

Here’s the RuntimeError message:

ruby xmlrpcClientTest.rb
Error:
xmlrpcClientTest.rb:9: undefined method `faultCode’ for
#RuntimeError:0x15bb30 (NameError)

Any ideas?

You call faultCode on a RuntimeError! See above.

Regards,

Michael

···

On Mon, 2002-10-21 at 17:57, Daniel Berger wrote:

Michael Neumann wrote:

Is ProcTable.ps really of type “Struct”? Or is it an object of an
user-defined class?

“ps()” is a class method that returns an array of structs. Each struct
contains such info as pid, ppid, pgid, etc. This is a C extension, btw.

This stand-alone example works fine

!/usr/bin/ruby
require ‘sys/proctable’
include Sys

List all pids

a = ProcTable.ps
a.each{ |pstruct| puts pstruct.pid.to_s }

Does ProcTable.ps return nil under some circumstances.

Impossible. That would mean no processes were running.

If that doesn’t help, please send me the definition of ProcTable.ps.

The source varies depending on platform (and would be a bit much to post here
anyway), but all platforms return an array of structs. The struct in
question is called “sProcStruct” and you can view its format within the
Init_proctable() call.

You can find the source at http://www.enteract.com/~mghall/ruby/sys/sys.html

Regards,

Dan

PS - I forgot to mention my platform earlier - Solaris 9

Just to see what would happen with regular Ruby structs (i.e. no extensions), I
tried adding this method to the xmlrpc server:

Return an array of structs

def get_aos
TestStruct = Struct.new(“TestStruct”,:name,:age)
dan = TestStruct.new(“Dan”,32)
joe = TestStruct.new(“Joe”,29)
a = []
a.push(dan,joe)
return a
end

This caused a “dynamic constant assignment” error, and I could only get it to
work if I declared the struct type outside the class. Could dynamic struct
generation be the source of the problem? If so, why?

Regards,

Dan

Hi,

From: Daniel Berger
Sent: Tuesday, October 22, 2002 6:27 AM

Is ProcTable.ps really of type “Struct”? Or is it an object of an
user-defined class?

“ps()” is a class method that returns an array of structs.
Each struct
contains such info as pid, ppid, pgid, etc. This is a C
extension, btw.

Run your xmlrpc standalone server with -d;

ruby -d test_ps_server.rb

Then run the client. It will dump the reason of
Internal Server Error.
Please show the error message.

I’m wondering it failed marshalling C struct, nil or
Bitnum, etc…

Regards,
// NaHi

Just to see what would happen with regular Ruby structs (i.e. no extensions), I
tried adding this method to the xmlrpc server:

Return an array of structs

def get_aos
TestStruct = Struct.new(“TestStruct”,:name,:age)
dan = TestStruct.new(“Dan”,32)
joe = TestStruct.new(“Joe”,29)
a =
a.push(dan,joe)
return a
end

Simply, don’t use a constant:

def get_aos
testStruct = Struct.new(“TestStruct”,:name,:age)
dan = testStruct.new(“Dan”,32)
joe = testStruct.new(“Joe”,29)
a =
a.push(dan,joe)
return a
end

You can also create the structs via Struct::TestStruct.new.

This caused a “dynamic constant assignment” error, and I could only get it to
work if I declared the struct type outside the class. Could dynamic struct
generation be the source of the problem? If so, why?

This is not a problem, if you don’t use constants. See above.
Note that you can also move the struct definition outside the method:

TestStruct = Struct.new(“TestStruct”,:name,:age)

def get_aos
dan = TestStruct.new(“Dan”,32)
joe = TestStruct.new(“Joe”,29)
a =
a.push(dan,joe)
return a
end

Regards,

Michael

···

On Mon, 2002-10-21 at 23:55, Daniel Berger wrote:

“NAKAMURA, Hiroshi” wrote:

Run your xmlrpc standalone server with -d;

ruby -d test_ps_server.rb

Then run the client. It will dump the reason of
Internal Server Error.
Please show the error message.

I’m wondering it failed marshalling C struct, nil or
Bitnum, etc…

Regards,
// NaHi

Here’s the error message I get:

ruby -d xmlrpcServerTest.rb
/usr/local/lib/ruby/site_ruby/1.6/xmlrpc/utils.rb:116: warning: &' interpreted as argument prefix [Tue Oct 22 07:50:21 2002] HttpServer 151.119.145.36:8889 start [Tue Oct 22 07:50:34 2002] HttpServer 151.119.145.36:8889 client:38032 my_host<1.2.3.4> connect in request_handler Exception RuntimeError’ at
/usr/local/lib/ruby/site_ruby/1.6/xmlrpc/create.rb:179 - Bignum is too
big! Must be signed 32-bit integer!

What do you make of that?

Regards,

Dan

Hi,

From: “Daniel Berger” djberge@qwest.com
Sent: Tuesday, October 22, 2002 10:53 PM

in request_handler
Exception `RuntimeError’ at
/usr/local/lib/ruby/site_ruby/1.6/xmlrpc/create.rb:179 - Bignum is too
big! Must be signed 32-bit integer!

What do you make of that?

Check if your config.rb
(/usr/local/lib/ruby/site_ruby/1.6/xmlrpc/config.rb or so)
allow you to use big int larger than +2^31.

Normally, XML-RPC spec does now allow you to send
a big integer. xmlrpc4r does not allow it by default for
interoperability, I think.

Regards,
// NaHi

“NAKAMURA, Hiroshi” wrote:

Hi,

From: “Daniel Berger” djberge@qwest.com
Sent: Tuesday, October 22, 2002 10:53 PM

in request_handler
Exception `RuntimeError’ at
/usr/local/lib/ruby/site_ruby/1.6/xmlrpc/create.rb:179 - Bignum is too
big! Must be signed 32-bit integer!

What do you make of that?

Check if your config.rb
(/usr/local/lib/ruby/site_ruby/1.6/xmlrpc/config.rb or so)
allow you to use big int larger than +2^31.

Normally, XML-RPC spec does now allow you to send
a big integer. xmlrpc4r does not allow it by default for
interoperability, I think.

Regards,
// NaHi

That was it! I had forgotten that was an option in the config.rb file.
Now, to find a faster parser!

Regards,

Dan