Would you please elaborate on that?

As I understand it there is no concurrent use of len happening here. It's a 
for loop and all calling to len is happening sequentially. Unless the 
channels make the code inside cases of one select statement concurrent - 
which will be super confusing for me.

On Sunday, August 28, 2016 at 8:03:10 PM UTC+4:30, Jan Mercl wrote:
>
> Using len(ch) like this in a concurrency scenario is a big no because then 
> the value you get carries 0 bits of useful information. It's not a data 
> race, it's worse, the race is semantic and not fixable without removing the 
> use of len(ch).
>
> On Sun, Aug 28, 2016, 17:26 dc0d <kaveh.sh...@gmail.com <javascript:>> 
> wrote:
>
>> TL;DR
>>
>> Does assigning a (buffered) channel, already in a variable, to a second 
>> variable, affects the result of len function?
>>
>> Long version:
>> What is happening here? - Code at the end; Go 1.7.
>>
>> *Output 1*:
>>
>> Nine times:
>> [  info ] 2016/08/28 19:51:28 LEN_BEFORE=0                               
>>      
>> [  info ] 2016/08/28 19:51:28 LEN=7                                     
>>       
>> [  info ] 2016/08/28 19:51:28 S00=7
>>
>> But if the second case gets commented like this:
>>
>> case <-limiter.C:
>>  // if len(actualBuffer) > 0 {
>>  // buffer = actualBuffer
>>  // } else {
>>  // buffer = nil
>>  // }
>>
>> It works as expected; *Output2*:
>>
>> [  info ] 2016/08/28 19:54:28 LEN_BEFORE=0                               
>>      
>> [  info ] 2016/08/28 19:54:28 LEN=7                                     
>>       
>> [  info ] 2016/08/28 19:54:28 S00=7                                     
>>       
>> [  info ] 2016/08/28 19:54:29 LEN_BEFORE=7                               
>>      
>> [  info ] 2016/08/28 19:54:30 LEN_BEFORE=7                               
>>      
>> [  info ] 2016/08/28 19:54:31 LEN_BEFORE=7                               
>>      
>> [  info ] 2016/08/28 19:54:32 LEN_BEFORE=7                               
>>      
>> [  info ] 2016/08/28 19:54:33 LEN_BEFORE=7                               
>>      
>> [  info ] 2016/08/28 19:54:34 LEN_BEFORE=7                               
>>      
>> [  info ] 2016/08/28 19:54:35 LEN_BEFORE=7                               
>>      
>> [  info ] 2016/08/28 19:54:36 LEN_BEFORE=7                
>> ...
>>
>> Code:
>>
>> package main
>>
>>
>> import (
>>  "log"
>>  "time"
>>
>>
>>  "github.com/comail/colog"
>> )
>>
>>
>> func status00Channeler() {
>>  <-start
>>
>>
>>  limiter := time.NewTicker(time.Second / maxMsgPerSec)
>>  fetchLimiter := time.NewTicker(time.Second)
>>
>>
>>  var buffer chan *Data
>>  actualBuffer := make(chan *Data, maxMsgPerSec)
>>  db, err := newDB()
>>  if err != nil {
>>  log.Panic(err)
>>  }
>>
>>
>> FIRST:
>>  for {
>>  select {
>>  case <-interrupted:
>>  break FIRST
>>  case <-limiter.C:
>>  // if len(actualBuffer) > 0 {
>>  // buffer = actualBuffer
>>  // } else {
>>  // buffer = nil
>>  // }
>>  case i := <-buffer:
>>  select {
>>  case status00 <- i: // will block here
>>  case <-interrupted:
>>  break FIRST
>>  }
>>  case <-fetchLimiter.C:
>>  log.Printf("LEN_BEFORE=%d", len(actualBuffer))
>>  if len(actualBuffer) > 0 {
>>  continue
>>  }
>>
>>
>>  s00, err := db.GetIncomings()
>>  if err != nil {
>>  log.Println(`error:`, err)
>>  time.Sleep(time.Second)
>>  continue
>>  }
>>  if s00 == nil || len(s00) == 0 {
>>  continue
>>  }
>>
>>
>>  FILL_BUFFER:
>>  for _, v := range s00 {
>>  select {
>>  case actualBuffer <- v:
>>  default:
>>  break FILL_BUFFER
>>  }
>>  }
>>
>>
>>  log.Printf("LEN=%d", len(actualBuffer))
>>  log.Printf("S00=%d", len(s00))
>>  }
>>  }
>> }
>>
>>
>> func main() {
>>  go status00Channeler()
>>  close(start)
>>
>>
>>  <-time.After(time.Second * 30)
>> }
>>
>>
>> var (
>>  status00 = make(chan *Data, maxMsgPerSec)
>> )
>>
>>
>> type Data struct{}
>>
>>
>> const (
>>  maxMsgPerSec = 60
>> )
>>
>>
>> func newDB() (*DB, error) {
>>  res := new(DB)
>>  return res, nil
>> }
>>
>>
>> func (db *DB) GetIncomings() ([]*Data, error) {
>>  var res []*Data
>>  res = append(res, &Data{})
>>  res = append(res, &Data{})
>>  res = append(res, &Data{})
>>  res = append(res, &Data{})
>>  res = append(res, &Data{})
>>  res = append(res, &Data{})
>>  res = append(res, &Data{})
>>
>>
>>  return res, nil
>> }
>>
>>
>> type DB struct{}
>>
>>
>> func init() {
>>  colog.Register()
>> }
>>
>>
>> var (
>>  start       = make(chan struct{})
>>  interrupted = make(chan struct{}) // comes from sys interrupts SIGINT, 
>> SIGTERM, etc
>> )
>>
>>
>> -- 
>> 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...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
> -- 
>
> -j
>

-- 
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.

Reply via email to