Hi guys!
I started experimenting with the new Concurrent.Promise/Concurrent.Future classes and implementing a HTTP client module using the promise/future stuff. The reason for this is that the async stuff in Protocols.HTTP.Query is far from intuitive. With promises/futures I think you get a super clean API that is easy to use.
So I started experimenting with this and would like to have your thoughts on the matter. Right now I put it as Protocols.HTTP.Promise but any suggestions on what to call it and where to place it would be appreciated.
Here’s some examples of how it would be used at the moment.
// Fetch a single URL
import Protocols.HTTP;
int main() { string url1 = ”http://pike.lysator.liu.se http://pike.lysator.liu.se/”;
Concurrent.Future q1 = Promise.get_url(url1);
q1->on_success(lambda (Protocols.HTTP.Query ok) { werror(”Successfully got %O\n”, ok->host); })->on_failure(lambda (Protocols.HTTP.Query fail) { werror(”%O failed!\n”, fail->host); });
return -1; }
// Fetch multiple URLs and call on_success in parallell for each request.
import Protocols.HTTP;
int main() { string url1 = ”http://pike.lysator.liu.se http://pike.lysator.liu.se/”; string url2 = ”http://roxen.com http://roxen.com/”;
Concurrent.Future q1 = Promise.get_url(url1); Concurrent.Future q2 = Promise.get_url(url2);
array(Concurrent.Future) all = ({ q1, q2 });
all->on_success(lambda (Protocols.HTTP.Query ok) { werror(”Successfully got %O\n”, ok->host); })->on_failure(lambda (Protocols.HTTP.Query fail) { werror(”%O failed!\n”, fail->host); });
return -1; }
// Fetch multiple URLs and call on_success when all has succeeded. // on_failure will be called immediately if one request fails.
import Protocols.HTTP;
int main() { string url1 = ”http://pike.lysator.liu.se http://pike.lysator.liu.se/”; string url2 = ”http://roxen.com http://roxen.com/”;
Concurrent.Future q1 = Promise.get_url(url1); Concurrent.Future q2 = Promise.get_url(url2); Concurrent.Future batch = Concurrent.results(({ q1, q2 }));
all->on_success(lambda (array(Protocols.HTTP.Query) ok) { werror(”Successfully got %O\n”, ok->host); })->on_failure(lambda (Protocols.HTTP.Query fail) { werror(”%O failed!\n”, fail->host); });
return -1; }
So, any thoughts on this?
Regards ----------------------------- Pontus Östlund Developer • Roxen AB +46 70-662 81 69
www.roxen.com http://www.roxen.com/ | twitter.com/roxen https://twitter.com/roxen
You might want to look into HTTP.Session, since that will handle things like reuse of connections and cookies. (I'm not saying it's intuitive, but it might be a better endpoint than Query for a Concurrent solution.)
(Query was never written not to have a layer on top of it.)
5 maj 2016 kl. 13:40 skrev Mirar @ Pike developers forum 10353@lyskom.lysator.liu.se:
You might want to look into HTTP.Session, since that will handle things like reuse of connections and cookies. (I'm not saying it's intuitive, but it might be a better endpoint than Query for a Concurrent solution.)
Good call! I’ll take a look at that.
(Query was never written not to have a layer on top of it.)
Yes, but still, stuff like this is a bit cumbersome I think:
Protocols.HTTP.Query q = Protocols.HTTP.Query();
q->set_callbacks( lambda (Protocols.HTTP.Query c) { c->timed_async_fetch( lambda (Protocols.HTTP.Query data) { werror(”Got data ok\n”); }, lambda (Protocols.HTTP.Query fail) { werror(”Failed getting data\n”); }); }, lambda (Protocols.HTTP.Query c) { werror(”Connection error\n”); });
Protocols.HTTP.do_async_method(”GET”, ”http://foo.bar http://foo.bar/”, 0, 0, q);
Cheers!
# Pontus
I just do things like
inherit Protocols.HTTP.Session;
... async_get_url("http://172.16.2.102/full_status.json%22,0, lambda(){}, con_data, con_fail); ... async_get_url("http://172.16.2.102/command.json", (["command":s]), lambda(){},lambda(){},lambda(){});
which doesn't feel very cumbersome. :)
6 maj 2016 kl. 10:30 skrev Mirar @ Pike developers forum 10353@lyskom.lysator.liu.se:
I just do things like
inherit Protocols.HTTP.Session;
[…] ... async_get_url("http://172.16.2.102/command.json", (["command":s]), lambda(){},lambda(){},lambda(){});
which doesn't feel very cumbersome. :)
Hehe, I agree to that, but it takes quite the Pike knowledge to get to that solution I would say.
The thing though with ”promises” is that you get more of a procedural style of programming even when you do async stuff, which tend to be more intuitive to most people.
# Pontus
pike-devel@lists.lysator.liu.se