Re: [go-nuts] synchronise read from two channels

2016-12-01 Thread omarshariffdontlikeit
Yup I thin I was frying my brain on this - it also led to questions such as 
"if I read a worker from the channel and there ISNT a URL waiting how do I 
write back into the channel making it available - what if more than one go 
routine is reading from the channel... etc"

I knew I was over complicating it I just couldnt see the forest for the 
trees! I assumed I wanted channels for the available and busy workers when 
really I wanted stacks.

thanks for the in-depth discussion - in future I will sleep on it next time 
and come at it afresh :)

(ironically I'd done exactly this before with stacks in an old project 
which is what gave me the lightbulb moment this morning)

Thanks everyone!

On Thursday, December 1, 2016 at 3:21:46 PM UTC, Jesper Louis Andersen 
wrote:
>
> On Wed, Nov 30, 2016 at 6:07 PM  
> wrote:
>
>> Hi, I'm having a bit of a slow day... I'm trying to synchronise two reads 
>> from two channels and can't get my fuzzy head round the problem.
>>
>>
> Go doesn't have support for an (atomic) read from multiple channels at 
> once. There are other systems which can do this (JoCaml, join-calculus, 
> Concurrent ML, Haskell's STM, Reagents[0] in Scala, ...)
>
> However, as you found out, one can often rearrange the code base as to 
> avoid the problem. There is also the problem of more advanced 
> select-constructs not being free in the performance sense: atomic sync on 
> multiple channels tend to be rather expensive.
>
> One reason it isn't that simple to implement is to consider the following 
> (hypothetical) snippet:
>
> select {
> case w := <-available && urlChan <- value:
> ..BODY..
> }
> }
>
> in which the atomic operation must simultaneously receive a message on the 
> 'available' channel and send a message on the 'urlChan' channel. And 
> further, since you introduced && to mean logical-and-between-channels, you 
> might as well introduce || to mean logical-or-between-channels. Once there, 
> you may want to introduce a new type
>
> event t
>
> for some type t alongside 'chan t'. Hence the expression (<-available) 
> becomes an expression of type 'event *worker' and now they can be composed 
> via && and ||. This means we can get rid of select since it is just an 
> expression which successively applies || to a slice of values. If we then 
> introduce an new statement, sync, which turns 'event t' into a 't', we are 
> done. And we have almost implemented the basis of Concurrent ML in the 
> process.
>
> In short, you could be opening a regular can of worms if you start 
> allowing for more complicated select-expressions. Hence the school of 
> keeping them relatively simple.
>
> [0] https://people.mpi-sws.org/~turon/reagents.pdf 
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] synchronise read from two channels

2016-12-01 Thread Jesper Louis Andersen
On Wed, Nov 30, 2016 at 6:07 PM  wrote:

> Hi, I'm having a bit of a slow day... I'm trying to synchronise two reads
> from two channels and can't get my fuzzy head round the problem.
>
>
Go doesn't have support for an (atomic) read from multiple channels at
once. There are other systems which can do this (JoCaml, join-calculus,
Concurrent ML, Haskell's STM, Reagents[0] in Scala, ...)

However, as you found out, one can often rearrange the code base as to
avoid the problem. There is also the problem of more advanced
select-constructs not being free in the performance sense: atomic sync on
multiple channels tend to be rather expensive.

One reason it isn't that simple to implement is to consider the following
(hypothetical) snippet:

select {
case w := <-available && urlChan <- value:
..BODY..
}
}

in which the atomic operation must simultaneously receive a message on the
'available' channel and send a message on the 'urlChan' channel. And
further, since you introduced && to mean logical-and-between-channels, you
might as well introduce || to mean logical-or-between-channels. Once there,
you may want to introduce a new type

event t

for some type t alongside 'chan t'. Hence the expression (<-available)
becomes an expression of type 'event *worker' and now they can be composed
via && and ||. This means we can get rid of select since it is just an
expression which successively applies || to a slice of values. If we then
introduce an new statement, sync, which turns 'event t' into a 't', we are
done. And we have almost implemented the basis of Concurrent ML in the
process.

In short, you could be opening a regular can of worms if you start allowing
for more complicated select-expressions. Hence the school of keeping them
relatively simple.

[0] https://people.mpi-sws.org/~turon/reagents.pdf

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] synchronise read from two channels

2016-11-30 Thread Michael Jones
It seems that you are fighting the helpful infrastructure, but I can’t be sure 
from what you’ve said.

 

You can (presumably) just do this:

 

For u := range streamOfUrls {

 For w := range availableWorkers {

   w.url = u

   activeWorkers <- w

 }

}

 

…but that is strange to me. Why not just have every worker loop for urls on its 
input channel:

 

for I := 0; I < workers; i++ {

    go Worker(urlChannel)

}

 

:

func Worker (uChan chan url) {

for u:= range uChan {

   do work with u

}

}

 

:

for ...range of urls… {

  urlChan <- nextUrl

}

close(urlChan) // will terminate all workers after their last task is assigned

 

From:  on behalf of 

Date: Wednesday, November 30, 2016 at 9:07 AM
To: golang-nuts 
Subject: [go-nuts] synchronise read from two channels

 

Hi, I'm having a bit of a slow day... I'm trying to synchronise two reads from 
two channels and can't get my fuzzy head round the problem.

 

I have a channel containing urls (which will be feed periodically by a named 
pipe by another program) and I have a cannel which consists of a pool of 
available workers. I'd like to synchronise these and put a worker into a third 
channel for active workers if there is a url in the channel and if there is an 
available worker.

 

Ideally I'd be able to do something like:

 

go func(urlChan <-chan *url.URL, availableWorkerChan <-chan *worker, 
activeWorkerChan chan<- *worker){

for {

select{

case w := <-availableWorkerChan && w.Url = <-urlChan:

activeWorkersChan <- w

}

}

}(a, b, c)

 

But obviously thats not right!

 

Can anyone offer my tired brain a clue?

 

Cheers!

Ben

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.