[racket] Using get-pure-port

10 views
Skip to first unread message

Shogo Yamazaki

unread,
Aug 18, 2011, 11:45:18 AM8/18/11
to us...@racket-lang.org
Hi,

I have a question about using get/post-pure-port.
I'm using Racket v5.1.2.3 and FreeBSD 8.2.
It seems tcp-port is still opened after I used get-pure-port.
How can I close this? The code is below.

(require net/url)

(let ((in (get-pure-port (string->url
"http://www.google.com/intl/en_com/images/srpr/logo3w.png"))))
(display-to-file (port->bytes in) (build-path (find-system-path
'home-dir) "google-logo1.png"))
(close-input-port in))

---In console---
% fsat | grep 'racket.*tcp'
myusername racket 948 5* internet stream tcp ca70b7e0
----------------
(I think fstat is similar with lsof in linux.)

I know that this won't happen when I use tcp-connect as below.

(let-values (((i o) (tcp-connect "www.google.com" 80)))
(display "GET /intl/en_com/images/srpr/logo3w.png HTTP/1.1\r\n\r\n" o)
(close-output-port o)
(display-to-file (second (regexp-split #"\r\n\r\n" (port->bytes i)))
(build-path (find-system-path 'home-dir) "google-logo2.png"))
(close-input-port i))

Although this isn't a big problem when I use the procedure only few times,
after used tens of thousands times it causes crash due to too many open file.
I will appreciate any help.

Shogo Yamazaki
_________________________________________________
For list-related administrative tasks:
http://lists.racket-lang.org/listinfo/users

Danny Yoo

unread,
Aug 18, 2011, 2:01:27 PM8/18/11
to Racket Users
(Sorry; forgot to reply-to-all; forwarding to the racket-users list as well)


---------- Forwarded message ----------
From: Danny Yoo <dy...@cs.wpi.edu>
Date: Thu, Aug 18, 2011 at 2:00 PM
Subject: Re: [racket] Using get-pure-port
To: Shogo Yamazaki <moquo...@gmail.com>


On Thu, Aug 18, 2011 at 11:45 AM, Shogo Yamazaki <moquo...@gmail.com> wrote:
> Hi,
>
> I have a question about using get/post-pure-port.
> I'm using Racket v5.1.2.3 and FreeBSD 8.2.
> It seems tcp-port is still opened after I used get-pure-port.
> How can I close this? The code is below.

[code omitted]

Hmm...  Do you see the same issue if you use a Racket custodian to
clean up the resources?


The Systems tutorial talks about custodians a bit:

   http://docs.racket-lang.org/more/index.html#(part._.Terminating_.Connections)


Your code would't have to change too much: it'd look something like:

   (define cust (make-custodian))
   (parameterize ([current-custodian cust])

       ;; .. your code, which opens ports and does other stuff

       (custodian-shutdown-all cust))


If you open ports in the context of a custodian, that custodian takes
responsibility for cleaning up resources when custodian-shutdown-all
gets called.

Shogo Yamazaki

unread,
Aug 18, 2011, 3:41:25 PM8/18/11
to Danny Yoo, us...@racket-lang.org
Thanks for your help.
The way you suggested worked for me.

By the way, I found that adding a line to the definition of
http-pipe-data in url-unit.rkt might resolve my problem either.
But I hardly understand what I'm doing.

(define (http-pipe-data chunked? ip op)
(if chunked?
(http-pipe-chunk ip op)
(begin
(copy-port ip op)
(close-input-port ip) ;### I added this line ###
(flush-output op)
(close-output-port op))))

Shogo Yamazaki

2011/8/19 Danny Yoo <dy...@cs.wpi.edu>:


> On Thu, Aug 18, 2011 at 11:45 AM, Shogo Yamazaki <moquo...@gmail.com> wrote:

>> Hi,
>>
>> I have a question about using get/post-pure-port.
>> I'm using Racket v5.1.2.3 and FreeBSD 8.2.
>> It seems tcp-port is still opened after I used get-pure-port.
>> How can I close this? The code is below.
>

> [code omitted]
>
> Hmm...  Do you see the same issue if you use a Racket custodian to
> clean up the resources?
>
>
> The Systems tutorial talks about custodians a bit:
>
>    http://docs.racket-lang.org/more/index.html#(part._.Terminating_.Connections)
>
>
> Your code would't have to change too much: it'd look something like:
>
>    (define cust (make-custodian))
>    (parameterize ([current-custodian cust])
>
>        ;; .. your code, which opens ports and does other stuff
>
>        (custodian-shutdown-all cust))
>
>
> If you open ports in the context of a custodian, that custodian takes
> responsibility for cleaning up resources when custodian-shutdown-all
> gets called.
>

_________________________________________________

Danny Yoo

unread,
Aug 18, 2011, 4:58:38 PM8/18/11
to Shogo Yamazaki, us...@racket-lang.org
> By the way, I found that adding a line to the definition of
> http-pipe-data in url-unit.rkt might resolve my problem either.
> But I hardly understand what I'm doing.
>
> (define (http-pipe-data chunked? ip op)
>  (if chunked?
>      (http-pipe-chunk ip op)
>      (begin
>        (copy-port ip op)
>        (close-input-port ip) ;### I added this line ###
>        (flush-output op)
>        (close-output-port op))))


That looks right to me. Nice catch.

Send it as a patch to the Racket developers! https://github.com/plt/racket

Eli Barzilay

unread,
Aug 18, 2011, 6:02:49 PM8/18/11
to Shogo Yamazaki, us...@racket-lang.org
Two hours ago, Shogo Yamazaki wrote:
> Thanks for your help.
> The way you suggested worked for me.
>
> By the way, I found that adding a line to the definition of
> http-pipe-data in url-unit.rkt might resolve my problem either.
> But I hardly understand what I'm doing.
>
> (define (http-pipe-data chunked? ip op)
> (if chunked?
> (http-pipe-chunk ip op)
> (begin
> (copy-port ip op)
> (close-input-port ip) ;### I added this line ###
> (flush-output op)
> (close-output-port op))))

Instead of the above, I've committed:

(define (purify-http-port in-port)
(define-values (in-pipe out-pipe) (make-pipe))
(thread
(λ ()
(define status (http-read-status in-port))
(define chunked? (http-read-headers in-port))
(http-pipe-data chunked? in-port out-pipe)
(close-input-port in-port))) ; <------------- this
in-pipe)

instead, so it's done in a more obvious place.

--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!

Reply all
Reply to author
Forward
0 new messages