unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Zelphir Kaltstahl <zelphirkaltstahl@posteo.de>
To: Guile User <guile-user@gnu.org>
Subject: Concurrently write (out) and read (in) from ports
Date: Tue, 11 Apr 2023 21:13:19 +0000	[thread overview]
Message-ID: <51e7fb71-8ed1-1215-6ddc-e0a45d4db59e@posteo.de> (raw)

Hi Guile users!

I am currently trying to concurrently write to an output port and read from the 
corresponding input port, but something I am doing wrong and it does not work as 
I expected it to.

Here is what I have tried so far:

~~~~
(import
  ;; ports
  (ice-9 popen)
  (ice-9 textual-ports)
  (ice-9 binary-ports)

  (ice-9 exceptions)
  (ice-9 match)
  (ice-9 threads)
  (ice-9 futures)
  ;; let-values form
  (srfi srfi-11))


;; Define a pair of corresponding in and out ports.
(define-values (in out)
   (match-let ([(in . out) (pipe)])
     ;; make out line buffered
     ;; (setvbuf out 'line)
     (values in out)))


;; Just a helper function.
(define seconds
   (λ (s)
     (* s (expt 10 6))))


(define line-reader
   (λ ()
     "Read from an IN-PORT and write to OUT-PORT."
     (let ([in-port (current-input-port)]
           [out-port (current-output-port)])
       (let loop ([line (get-line in-port)])
         (simple-format #t "reader: reading from in-port\n")
         (unless (eof-object? line)
           (put-string out-port line)
           (loop (get-line in-port)))))))


;; Start writing endlessly.
(define writer-future
   (future
    (with-output-to-port out
      (λ () (endless-writer)))))


(with-output-to-port (current-output-port)
   (λ ()
     (with-input-from-port in
       (line-reader))))
~~~~

However, this does not work:

~~~~
guile -L . example.scm
~~~~

Does not display anything.

I also tried with explicitly passed ports:

~~~~
(import
  ;; ports
  (ice-9 popen)
  (ice-9 textual-ports)
  (ice-9 binary-ports)
  (ice-9 exceptions)
  ;; receive form
  ;; (ice-9 receive)
  ;; pattern matching
  (ice-9 match)
  ;; concurrency
  (ice-9 threads)
  (ice-9 futures)
  ;; let-values form
  (srfi srfi-11))


(define-values (in out)
   (match-let ([(in . out) (pipe)])
     ;; make out line buffered
     ;; (setvbuf out 'none)
     (values in out)))


(define seconds
   (λ (s)
     (* s (expt 10 6))))


(define endless-writer
   (λ (out)
     (let loop ()
       (simple-format #t "writer: writing message to output port\n")
       (put-string out "Hello!\n")
       ;; forcing the output should be unnecessary
       ;; (force-output out)
       (usleep (seconds 1))
       (loop))
     'never))


(define line-reader
   (lambda* (in-port out-port)
     "Read from an IN-PORT and write to OUT-PORT."
     (let loop ([line (get-line in-port)])
       (simple-format #t "reader: reading from in-port\n")
       (unless (eof-object? line)
         (put-string out-port line)
         (loop (get-line in-port))))))


;; Start writing endlessly.
(define writer-future (future (endless-writer out)))


;; Read from in-port, which should be the corresponding one to the
;; out-port, to which the endless-writer writes its output. Output to
;; the current output port, so that the output is visible. Read some
;; number of bytes at once. Limits the amount of memory needed for the
;; string.

(reader in (current-output-port) #:bytes-count 16)

;; That does not output anything.

(line-reader in (current-output-port))

;; That does not output anything.
~~~~

But:

~~~~
(call-with-input-string "Test!\n"
   (lambda (in)
     (line-reader in (current-output-port))))
~~~~

Does output things.

So I am thinking my endless writer must be wrong. But I cannot figure out what 
is wrong. Or maybe I am misunderstanding how the in and out port of (pipe) 
correspond.

How can I make this work?

Also side question: Is this usage of futures "OK", or should I be using threads? 
Thought futures are more lightweight than threads in this case.

Regards,
Zelphir

-- 
repositories:https://notabug.org/ZelphirKaltstahl


                 reply	other threads:[~2023-04-11 21:13 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51e7fb71-8ed1-1215-6ddc-e0a45d4db59e@posteo.de \
    --to=zelphirkaltstahl@posteo.de \
    --cc=guile-user@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).