LordVeovis / xmlrpc

A port of CookComputing.XmlRpcV2 for dotnet core 2
MIT License
33 stars 21 forks source link

Multithreaded usage : requests are not sent #18

Open Sunslash opened 4 years ago

Sunslash commented 4 years ago

I am trying to send multiple parallel requests to a Xml-RPC in order to reduce the response time.

The proper way to do it would be to use system.multicall, but this library does not seem to support it.

What I did is start two async tasks and wait for both calls to be completed, something like ` var newStatusTask = Task.Run(() => { return _com.GetStatusStd(); }) ; var newCounterTask = Task.Run(() => { return _com.GetInternalCounters(); }) ;

        var newStatusXml = await newStatusTask;
        var newCountersXml = await newCounterTask;

`

This mostly work, but sometimes one of the requests is not sent at all and leads to a timeout. I confirmed this with Wireshark and looping over both calls every 300ms.

If I wait for the first request to be completed before sending the second one, everything works fine. However for this application the additional ~100ms required to do this could reduce the overall performance.

Is there a proper way to handle parallel xml-rpc calls ?

LordVeovis commented 3 years ago

I don't understand what you mean by the library does not support system.multicall. In XML-RPC, the server exposes methods that can then be called with the help of this library. In other words, system.multicall I don't think system.multicall to be a special method, that's just a method that may be or may not be exposed by the server.

In one of my project, I did not used sytem.multicall but t.multicall, p.multicall and f.multicall to interact with rtorrent without any issue. The call is weird however as I had to put an empty string as the first argument:

# method definition
[XmlRpcMethod("d.multicall2")]
object[][] TorrentInfos(string empty, string view, params string[] commands);

# call
var res = instance.TorrentInfos("", view, "d.name=", "d.complete=", "d.load_date=", "d.down.rate=", "d.up.rate=", "d.completed_bytes=", "d.up.total=", "d.ratio=", "d.size_bytes=", "d.hash=", "d.is_active=", "d.state=", "d.is_open=", "d.custom1=", "d.custom=date", "d.is_multi_file=", "d.is_hash_checking=", "d.custom=admin");

About your workaround, even though "it works" on fast calls, I can't confirm the library be multithread-safe everywhere.