Replies: 5 comments 19 replies
-
Maybe |
Beta Was this translation helpful? Give feedback.
-
@aarroyoc @Skgland @bakaq I'm happy to take a swing at implementing this on the rust side. It will be sub-optimal most likely but enough to get things moving. The best outcome would be "slicing I/O". What I mean by this is something like ?- get_n_chars(Stream, N, Chars, [timeout(Seconds), close(false)]) where It would be better to apply this consistently across the back-end rather than ad-hoc, but this is where my rust knowledge is not strong enough to know how to apply this consistently for robust behavior. Also @triska (and anyone else), I would be curious if you had any thoughts on the best Prolog semantics for this. Should this always be applied only to MotivationI believe if we are able to achieve slicing I/O, we can make some extremely powerful tools (such as web servers and Erlang-style processes) without the need to implement OS-level threading, and this would dramatically increase the power and reach of the applications which Scryer is suited for. Because it does not rely on OS-level threading, it would also be applicable to WASM/javascript code, and therefor very useful as a web language! |
Beta Was this translation helpful? Give feedback.
-
@mthom or @Skgland do we need all of this #[bitfield]
#[repr(u64)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct StreamOptions {
pub stream_type: StreamType,
pub reposition: bool,
pub eof_action: EOFAction,
pub has_alias: bool,
pub alias: B59
// pub stream_timeout: B16
} |
Beta Was this translation helpful? Give feedback.
-
Ok, I have a very crappy proof of concept for non-blocking I/O by focusing on The general technique works like this:
This causes ?- process_create("bash", ["-c", "sleep 1; echo 'hey'"], [stdout(pipe(Stream))]),
length(Cs, 4),
( maplist(get_char(Stream), Cs)
; sleep(1)
),
length(Cs1, 4),
maplist(get_char(Stream), Cs1).
%@ Stream = '$stream'(0x55f9461332a0), Cs = [_A,_B,_C,_D], Cs1 = "hey\n". Unfortunately, this broke something somewhere else: ?- process_create("bash", ["-c", "sleep 1; echo 'hey'"], [stdout(pipe(Stream))]),
( get_n_chars(Stream, N, Cs)
; sleep(1)
),
get_n_chars(Stream, N1, Cs1).
%@ error(syntax_error(input_output_error),get_n_chars/2). If you can happen to spot any obvious errors in here, I'd appreciate it: master...jjtolton:scryer-prolog:nonblocking-io-poc (yes, most of this was tortured out of a carefully supervised LLM -- I claim no craftsman ship here. My rust is not nearly strong enough to do this task justice, but it needs to be done...) |
Beta Was this translation helpful? Give feedback.
-
Update:, % this works great!
request_response_loop(Stream) :-
get_n_chars(Stream, N, Chars),
if_(N=0,
sleep(0.1),
( format("~s~n", [Chars]),
format(Stream, "Received: ~s", [Chars]),
handle_term(Stream, Chars),
request_response_loop(Stream)
)
),
request_response_loop(Stream). |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I am curious if anyone has any thoughts on what it might take to achieve some semantics along the lines of
time_out/3
?The purpose of this is I want to be able to use Scryer async mechanics for streaming over chunks of socket data so that we can handle multiple connections at the same time and get intermediate data without needing for the entire process to terminate for use with
get_n_chars/3
. The best way I can think to do this would be to do goal timeouts on blocking I/O. It's not perfect but it would be a good start.It sounds like we might need to have some kind of watchdog timer on the rust side?
Beta Was this translation helpful? Give feedback.
All reactions