Checking if socket is operational without triggering exception

Hello,

Is there a way to check if a socket (input or output) is active before trying to write to and read from a stream, without triggering an exception – i.e. as a precondition.

thank you,

Dan

In the meantime i am wrapping predicates in catch blocks – was hoping there is a better way.

I can think of a lot of possible meanings for “socket is operational” … can you be a bit more precise?

If you mean that you’re able to read from (or write to) the socket, it’s possible for a failure to occur between when you check it and actually do the read (e.g., the ethernet cable is unplugged between the check and the read), so you need catch anyway. (Also, in some situations you can’t always rely on the catch because it can take a long time before a socket gives an error … before TCP/IP KeepAlive became common, it could take 2 hours to time out a socket read, if I remember correctly.) Network programming can be tricky and the code can get messy if all the possibilities are covered thoroughly.

In addition to catch, you might also consider setup_call_cleanup in some situations, e.g. for cleanly closing the socket and ensuring you’ve read everything.

1 Like

Hi Peter,

Thank you for your comments – very insightful.

So, beside a catch I need to also check timeouts – not sure yet how i would do this, and all of this would need to be asynchronously orchestrated.

I am curious, what is common practice – how long does one keep a socket open – i could do this across a single query, or across a user session (whatever that is)…

I guess, i could also have some background polling going on that tests a socket periodically, and “refreshes” it, in case it gets unusable (i.e. traps, or doesn’t respond in a reasonable timely manner).

Dan

Take this with a grain of salt as I have not used sockets with SWI-Prolog nor did I look at the test cases for the source to find examples.

My understanding is that a socket is also a stream and so stream_property/2 and is_stream/1 can be used.

Also see: Difference between Stateless and Stateful Protocol

HTH

If you are in control of both ends of the connection, you might want to use websockets rather than raw sockets. They provide some more options, such as timeouts and multi-threaded handlers.

There are lots of gotchas with network programming; in theory, many of them also exist for regular I/O (after all, a network connection looks like a stream), but are seldom encountered; so most programmers aren’t aware of the issues (e.g., look at the “careful programmer” comments with the standard Unix close function). So, if you can use an existing layer above raw sockets (such as websockets), that’s usually a good idea.

Thanks, Peter.

I don’t have control – i am reading from the conceptbase server which is socket based. – unless, i decide to implement websockets on the conceptbase side --perhaps a future project – although, i think, if i were to extend conceptbase in the future i may want to (first) provide it as a module to swi-prolog, so it can be a “native” backend KB.

Dan

Websocket.pl can give you some ideas. For example, it has a call to set_stream(HTTPIn, timeout(TimetOut), which will throw an exception on timeout.
There’s also wait_for_input/3.