Is there a #upToEnd kind of read for a none blocking GsSocket?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Is there a #upToEnd kind of read for a none blocking GsSocket?

GLASS mailing list
I am trying to use GsHostProcess and provide a polling API for it. Something like this:


------

runAndWaitPollingEvery: pollingMsPeriod onExitDo: anExitBlock

  | process delay outStream errStream |
  delay := Delay forMilliseconds: pollingMsPeriod.
  outStream := WriteStream new.
  errStream := WriteStream new.
  
  process := GsHostProcess fork: aCommandString.
  
  [ process childHasExited ]
  whileFalse: [
delay wait. 
                "retrieve all we have in the pipes to make room and avoid locks"
outStream nextPutAll: process stdout upToEnd.
errStream nextPutAll: process stderr upToEnd.
].

  outStream nextPutAll: process stdout upToEnd.
  errStream nextPutAll: process stderr upToEnd.

  process stdout close. 
  process stderr close. 
  
  aBlock cull: outStream contents cull: errStream contents

--------

I tried to implement an GsSocket >> upToEnd like this:

-----
upToEnd
| newStream buffer nextBytes |
buffer := buffer1 species new: 1000.
newStream := WriteStream on: (buffer1 species new: 100).
[self readWillNotBlock not or: [(nextBytes := self read: buffer size into: buffer startingAt: 1) isEmpty]]
whileFalse: [newStream nextPutAll: nextBytes].
^ newStream contents
-----

Does that sound correct? 

Thanks a lot in advance, 


--

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass
Reply | Threaded
Open this post in threaded view
|

Re: Is there a #upToEnd kind of read for a none blocking GsSocket?

Richard Sargent
Administrator
GLASS mailing list wrote
I am trying to use GsHostProcess and provide a polling API for it.
Something like this:


------

runAndWaitPollingEvery: pollingMsPeriod onExitDo: anExitBlock

  | process delay outStream errStream |
  delay := Delay forMilliseconds: pollingMsPeriod.
  outStream := WriteStream new.
  errStream := WriteStream new.

  process := GsHostProcess fork: aCommandString.

  [ process childHasExited ]
  whileFalse: [
delay wait.
                "retrieve all we have in the pipes to make room and avoid
locks"
outStream nextPutAll: *process stdout upToEnd.*
errStream nextPutAll: *process stderr upToEnd.*
].

  outStream nextPutAll: *process stdout upToEnd.*
  errStream nextPutAll: *process stderr upToEnd.*

  process stdout close.
  process stderr close.

  aBlock cull: outStream contents cull: errStream contents

--------

I tried to implement an GsSocket >> upToEnd like this:
Mariano, I like what you are trying to do. But, I think the name you have chosen is flawed.

The fact that you had to write a comment where you used it to explain what you meant is a red flag for that. "retrieve all we have in the pipes" is quite different from the usual Stream implementation for #upToEnd. It sounds like you want to use a name more like #allAvailable. (Note that I don't think that's the best possible name, but I don't have a better one at this moment.)


-----
upToEnd
| newStream buffer nextBytes |
buffer := buffer1 species new: 1000.
newStream := WriteStream on: (buffer1 species new: 100).
[self readWillNotBlock not or: [(nextBytes := self read: buffer size into:
buffer startingAt: 1) isEmpty]]
whileFalse: [newStream nextPutAll: nextBytes].
^ newStream contents
-----

Does that sound correct?

Thanks a lot in advance,


--
Mariano
http://marianopeck.wordpress.com

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass
Reply | Threaded
Open this post in threaded view
|

Re: Is there a #upToEnd kind of read for a none blocking GsSocket?

GLASS mailing list

On Wed, Jul 5, 2017 at 5:44 PM, Richard Sargent via Glass <[hidden email]> wrote:
GLASS mailing list wrote
> I am trying to use GsHostProcess and provide a polling API for it.
> Something like this:
>
>
> ------
>
> runAndWaitPollingEvery: pollingMsPeriod onExitDo: anExitBlock
>
>   | process delay outStream errStream |
>   delay := Delay forMilliseconds: pollingMsPeriod.
>   outStream := WriteStream new.
>   errStream := WriteStream new.
>
>   process := GsHostProcess fork: aCommandString.
>
>   [ process childHasExited ]
>   whileFalse: [
> delay wait.
>                 "retrieve all we have in the pipes to make room and avoid
> locks"
> outStream nextPutAll: *process stdout upToEnd.*
> errStream nextPutAll: *process stderr upToEnd.*
> ].
>
>   outStream nextPutAll: *process stdout upToEnd.*
>   errStream nextPutAll: *process stderr upToEnd.*
>
>   process stdout close.
>   process stderr close.
>
>   aBlock cull: outStream contents cull: errStream contents
>
> --------
>
> I tried to implement an GsSocket >> upToEnd like this:

Mariano, I like what you are trying to do. But, I think the name you have
chosen is flawed.

The fact that you had to write a comment where you used it to explain what
you meant is a red flag for that. "retrieve all we have in the pipes" is
quite different from the usual Stream implementation for #upToEnd. It sounds
like you want to use a name more like #allAvailable. (Note that I don't
think that's the best possible name, but I don't have a better one at this
moment.)


Hi Richard, 

Thanks, #allAvailable is indeed better. However, note that such a method may be way too general to be put in GsSocket (I don't know). It might only make sense when using pipes underneath? I don't know. Probably, I will add it as a extension method with my app prefix (#fa) and call it #faAllAvailableInPipe (or something to make clear it may only work for pipes....if this is the case).

Aside from the selector, what do you think about the contents? does that sound correct? 

Thanks! 

 


> -----
> upToEnd
> | newStream buffer nextBytes |
> buffer := buffer1 species new: 1000.
> newStream := WriteStream on: (buffer1 species new: 100).
> [self readWillNotBlock not or: [(nextBytes := self read: buffer size into:
> buffer startingAt: 1) isEmpty]]
> whileFalse: [newStream nextPutAll: nextBytes].
> ^ newStream contents
> -----
>
> Does that sound correct?
>
> Thanks a lot in advance,
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>
> _______________________________________________
> Glass mailing list

> Glass@.gemtalksystems

> http://lists.gemtalksystems.com/mailman/listinfo/glass





--
View this message in context: http://forum.world.st/Is-there-a-upToEnd-kind-of-read-for-a-none-blocking-GsSocket-tp4953564p4953607.html
Sent from the GLASS mailing list archive at Nabble.com.
_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass



--

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass
Reply | Threaded
Open this post in threaded view
|

Re: Is there a #upToEnd kind of read for a none blocking GsSocket?

Richard Sargent
Administrator
GLASS mailing list wrote
On Wed, Jul 5, 2017 at 5:44 PM, Richard Sargent via Glass <
[hidden email]> wrote:

> GLASS mailing list wrote
> > I am trying to use GsHostProcess and provide a polling API for it.
> > Something like this:
> >
> >
> > ------
> >
> > runAndWaitPollingEvery: pollingMsPeriod onExitDo: anExitBlock
> >
> >   | process delay outStream errStream |
> >   delay := Delay forMilliseconds: pollingMsPeriod.
> >   outStream := WriteStream new.
> >   errStream := WriteStream new.
> >
> >   process := GsHostProcess fork: aCommandString.
> >
> >   [ process childHasExited ]
> >   whileFalse: [
> > delay wait.
> >                 "retrieve all we have in the pipes to make room and avoid
> > locks"
> > outStream nextPutAll: *process stdout upToEnd.*
> > errStream nextPutAll: *process stderr upToEnd.*
> > ].
> >
> >   outStream nextPutAll: *process stdout upToEnd.*
> >   errStream nextPutAll: *process stderr upToEnd.*
> >
> >   process stdout close.
> >   process stderr close.
> >
> >   aBlock cull: outStream contents cull: errStream contents
> >
> > --------
> >
> > I tried to implement an GsSocket >> upToEnd like this:
>
> Mariano, I like what you are trying to do. But, I think the name you have
> chosen is flawed.
>
> The fact that you had to write a comment where you used it to explain what
> you meant is a red flag for that. "retrieve all we have in the pipes" is
> quite different from the usual Stream implementation for #upToEnd. It
> sounds
> like you want to use a name more like #allAvailable. (Note that I don't
> think that's the best possible name, but I don't have a better one at this
> moment.)
>
>
Hi Richard,

Thanks, #allAvailable is indeed better. However, note that such a method
may be way too general to be put in GsSocket (I don't know). It might only
make sense when using pipes underneath? I don't know. Probably, I will add
it as a extension method with my app prefix (#fa) and call it
#faAllAvailableInPipe (or something to make clear it may only work for
pipes....if this is the case).

Aside from the selector, what do you think about the contents? does that
sound correct?
#read:into:startingAt: claims it "Returns the number of bytes read, or nil if an error,  or 0 if EOF on the receiver." Structurally, it looks good. Correct the return value and add the bytes to the stream instead of the number of bytes and it should work.

As a matter of style, I would apply de Morgan's rule to the loop to make it more comprehensible.
[self readWillNotBlock and: [(bytesRead := self read: buffer size into: buffer startingAt: 1) > 0]]
whileTrue: [newStream nextPutAll: (buffer copyFrom: 1 to: bytesRead)].


Thanks!



>
>
> > -----
> > upToEnd
> > | newStream buffer nextBytes |
> > buffer := buffer1 species new: 1000.
> > newStream := WriteStream on: (buffer1 species new: 100).
> > [self readWillNotBlock not or: [(nextBytes := self read: buffer size
> into:
> > buffer startingAt: 1) isEmpty]]
> > whileFalse: [newStream nextPutAll: nextBytes].
> > ^ newStream contents
> > -----
> >
> > Does that sound correct?
> >
> > Thanks a lot in advance,
> >
> >
> > --
> > Mariano
> > http://marianopeck.wordpress.com
> >
> > _______________________________________________
> > Glass mailing list
>
> > Glass@.gemtalksystems
>
> > http://lists.gemtalksystems.com/mailman/listinfo/glass
>
>
>
>
>
> --
> View this message in context: http://forum.world.st/Is-
> there-a-upToEnd-kind-of-read-for-a-none-blocking-GsSocket-
> tp4953564p4953607.html
> Sent from the GLASS mailing list archive at Nabble.com.
> _______________________________________________
> Glass mailing list
> [hidden email]
> http://lists.gemtalksystems.com/mailman/listinfo/glass
>



--
Mariano
http://marianopeck.wordpress.com

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass
Reply | Threaded
Open this post in threaded view
|

Re: Is there a #upToEnd kind of read for a none blocking GsSocket?

GLASS mailing list


On Wed, Jul 5, 2017 at 6:22 PM, Richard Sargent via Glass <[hidden email]> wrote:
GLASS mailing list wrote
> On Wed, Jul 5, 2017 at 5:44 PM, Richard Sargent via Glass <

> glass@.gemtalksystems

>> wrote:
>
>> GLASS mailing list wrote
>> > I am trying to use GsHostProcess and provide a polling API for it.
>> > Something like this:
>> >
>> >
>> > ------
>> >
>> > runAndWaitPollingEvery: pollingMsPeriod onExitDo: anExitBlock
>> >
>> >   | process delay outStream errStream |
>> >   delay := Delay forMilliseconds: pollingMsPeriod.
>> >   outStream := WriteStream new.
>> >   errStream := WriteStream new.
>> >
>> >   process := GsHostProcess fork: aCommandString.
>> >
>> >   [ process childHasExited ]
>> >   whileFalse: [
>> > delay wait.
>> >                 "retrieve all we have in the pipes to make room and
>> avoid
>> > locks"
>> > outStream nextPutAll: *process stdout upToEnd.*
>> > errStream nextPutAll: *process stderr upToEnd.*
>> > ].
>> >
>> >   outStream nextPutAll: *process stdout upToEnd.*
>> >   errStream nextPutAll: *process stderr upToEnd.*
>> >
>> >   process stdout close.
>> >   process stderr close.
>> >
>> >   aBlock cull: outStream contents cull: errStream contents
>> >
>> > --------
>> >
>> > I tried to implement an GsSocket >> upToEnd like this:
>>
>> Mariano, I like what you are trying to do. But, I think the name you have
>> chosen is flawed.
>>
>> The fact that you had to write a comment where you used it to explain
>> what
>> you meant is a red flag for that. "retrieve all we have in the pipes" is
>> quite different from the usual Stream implementation for #upToEnd. It
>> sounds
>> like you want to use a name more like #allAvailable. (Note that I don't
>> think that's the best possible name, but I don't have a better one at
>> this
>> moment.)
>>
>>
> Hi Richard,
>
> Thanks, #allAvailable is indeed better. However, note that such a method
> may be way too general to be put in GsSocket (I don't know). It might only
> make sense when using pipes underneath? I don't know. Probably, I will add
> it as a extension method with my app prefix (#fa) and call it
> #faAllAvailableInPipe (or something to make clear it may only work for
> pipes....if this is the case).
>
> Aside from the selector, what do you think about the contents? does that
> sound correct?

#read:into:startingAt: claims it "Returns the number of bytes read, or nil
if an error,  or 0 if EOF on the receiver." Structurally, it looks good.

Yes, exactly. But as those comments where written for GsSocket itself, and in this case we are using GsSocket but with underlying OS pipes (rather than underlying OS sockets) I was not 100% sure it should be ok. 
 
Correct the return value and add the bytes to the stream instead of the
number of bytes and it should work.

As a matter of style, I would apply de Morgan's rule to the loop to make it
more comprehensible.
[self readWillNotBlock and: [(bytesRead := self read: buffer size into:
buffer startingAt: 1) > 0]]
whileTrue: [newStream nextPutAll: (buffer copyFrom: 1 to: bytesRead)].


Yes, that makes sense. Another thing I am not sure is whether I should use String or ByteArray as buffers (I am not sure wether the streams are opened as binary or text). 

Anyway..... I am going to sleep now but this is what I will end up testing tomorrow (with the polling API of the first email )

GsSocket >> faAllAvailableInPipe
| newStream buffer nextBytes bytesRead |
buffer := String new: 1000.
newStream := WriteStream on: (String new: 100).
[self readWillNotBlock and: [(bytesRead := self read: buffer size into:
buffer startingAt: 1) > 0]]
whileTrue: [newStream nextPutAll: (buffer copyFrom: 1 to: bytesRead)].
^ newStream contents


Thanks for your help. 

 


> Thanks!
>
>
>
>>
>>
>> > -----
>> > upToEnd
>> > | newStream buffer nextBytes |
>> > buffer := buffer1 species new: 1000.
>> > newStream := WriteStream on: (buffer1 species new: 100).
>> > [self readWillNotBlock not or: [(nextBytes := self read: buffer size
>> into:
>> > buffer startingAt: 1) isEmpty]]
>> > whileFalse: [newStream nextPutAll: nextBytes].
>> > ^ newStream contents
>> > -----
>> >
>> > Does that sound correct?
>> >
>> > Thanks a lot in advance,
>> >
>> >
>> > --
>> > Mariano
>> > http://marianopeck.wordpress.com
>> >
>> > _______________________________________________
>> > Glass mailing list
>>
>> > Glass@.gemtalksystems
>>
>> > http://lists.gemtalksystems.com/mailman/listinfo/glass
>>
>>
>>
>>
>>
>> --
>> View this message in context: http://forum.world.st/Is-
>> there-a-upToEnd-kind-of-read-for-a-none-blocking-GsSocket-
>> tp4953564p4953607.html
>> Sent from the GLASS mailing list archive at Nabble.com.
>> _______________________________________________
>> Glass mailing list
>>

> Glass@.gemtalksystems

>> http://lists.gemtalksystems.com/mailman/listinfo/glass
>>
>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>
> _______________________________________________
> Glass mailing list

> Glass@.gemtalksystems

> http://lists.gemtalksystems.com/mailman/listinfo/glass





--
View this message in context: http://forum.world.st/Is-there-a-upToEnd-kind-of-read-for-a-none-blocking-GsSocket-tp4953564p4953613.html
Sent from the GLASS mailing list archive at Nabble.com.
_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass



--

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass