Skip to content

sea-postkassa/condchan

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Forked from https://gitlab.com/jonas.jasas/condchan

CondChan cancellable sync.Cond

CondChan is a sync.Cond with the ability to wait in select statement.

  • Adds waiting in select statement feature
  • Implements all sync.Cond interface
  • Passes all sync.Cond tests
  • Implemented using channels
  • Just ~37% slower comparing to sync.Cond

go report card pipeline status coverage report godoc

Installation

Simple install the package to your $GOPATH with the go tool from shell:

$ go get gitlab.com/jonas.jasas/condchan

Make sure Git is installed on your machine and in your system's PATH.

Usage examples

Timeout example

In this example CondChan is created and endlessly waiting on it. Select method is used for the waiting. Method accepts func argument. Signaling channel is provided inside func that should be used in select statement together with the other channels that can interrupt waiting.

func timeoutExample()  {
	cc := condchan.New(&sync.Mutex{})
	timeoutChan := time.After(time.Second)

	cc.L.Lock()
	// Passing func that gets channel c that signals when
	// Signal or Broadcast is called on CondChan
	cc.Select(func(c <-chan struct{}) { // Waiting with select
		select {
		case <-c:   // Never ending wait
		case <-timeoutChan:
			fmt.Println("Hooray! Just escaped from the eternal wait.")
		}
	})
	cc.L.Unlock()
}

Output:

Hooray! Just escaped from the eternal wait.

Broadcast example

This example is using Wait and Select methods for simultaneous wait on same CondChan. Waiter "Patience" is waiting 3s and waiter "Impatience" is waiting 1s while job is done in 2s. Waiter "Impatience" will be cancelled with timeoutChan. Waiter "Patience" will receive signal on channel c.

func broadcastExample()  {
	cc := condchan.New(&sync.Mutex{})

	var jobResult string
	go func() {
		time.Sleep(time.Second*2)  // Imitating long job
		cc.L.Lock()
		jobResult = "CANDY"
		cc.L.Unlock()
		cc.Broadcast()  // Letting know all waiters that job is done
	}()

	go waiter(cc, "Patience", time.Second*3, &jobResult)
	go waiter(cc, "Impatience", time.Second*1, &jobResult)

	cc.L.Lock()
	cc.Wait()   // Waiting like on sync.Cond
	cc.L.Unlock()
	time.Sleep(time.Second)
}

func waiter(cc *condchan.CondChan, name string, wait time.Duration, jobResult *string) {
	timeoutChan := time.After(wait)
	cc.L.Lock()
	cc.Select(func(c <-chan struct{}) { // Waiting with select
		select {
		case <-c:
			log.Printf("%s: I received what I been waiting for - %s", name, *jobResult)
		case <-timeoutChan:
			log.Printf("%s: I can't wait much longer", name)
		}
	})
	cc.L.Unlock()
}

Output:

2019/01/27 22:48:02 Impatience: I can't wait much longer
2019/01/27 22:48:03 Patience: I received what I been waiting for - CANDY

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages