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
---------- 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.
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.
>
_________________________________________________
That looks right to me. Nice catch.
Send it as a patch to the Racket developers! https://github.com/plt/racket
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!