Skip to content

Commit

Permalink
Merge pull request #7 from gomicro/callback
Browse files Browse the repository at this point in the history
Callback blocker
  • Loading branch information
dan9186 authored Apr 11, 2021
2 parents 61a8d37 + f44b1a9 commit 3b76a9e
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 31 deletions.
38 changes: 38 additions & 0 deletions cbblocker/cbblocker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cbblocker

import (
"time"
)

type Blocker struct {
callback func() error
duration time.Duration
}

func New(callback func() error, poll time.Duration) *Blocker {
return &Blocker{
callback: callback,
duration: poll,
}
}

func (g *Blocker) Blockit() <-chan bool {
pass := make(chan bool)

go func() {
for {
err := g.callback()
if err != nil {
<-time.After(g.duration)
continue
}

pass <- true
close(pass)

break
}
}()

return pass
}
41 changes: 41 additions & 0 deletions cbblocker/dbblocker_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package cbblocker_test

import (
"fmt"
"testing"
"time"

"github.com/gomicro/blockit/cbblocker"

"github.com/franela/goblin"
. "github.com/onsi/gomega"
)

func TestCallbackBlockers(t *testing.T) {
g := goblin.Goblin(t)
RegisterFailHandler(func(m string, _ ...int) { g.Fail(m) })

g.Describe("Callback Blocking", func() {
g.It("should block until callback returns no error", func() {
ep := eventualPass{}

b := cbblocker.New(ep.do, 10*time.Millisecond)
Eventually(<-b.Blockit()).Should(BeTrue())
Expect(ep.Fails).To(Equal(4))
})
})
}

type eventualPass struct {
Fails int
}

func (ep *eventualPass) do() error {
if ep.Fails > 3 {
return nil
}

ep.Fails++

return fmt.Errorf("didn't pass")
}
35 changes: 4 additions & 31 deletions dbblocker/dbblocker.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,11 @@ package dbblocker
import (
"database/sql"
"time"
)

// Blocker represents a SQL database connection to monitor for connectivity
// and block until a connection is established.
type Blocker struct {
db *sql.DB
}
"github.com/gomicro/blockit/cbblocker"
)

// New takes a SQL database object and returns a newly instantiated Blocker
func New(db *sql.DB) *Blocker {
return &Blocker{db: db}
}

// Blockit meets the blocker interface. It returns a read only channel that will
// receive true when the database is connected.
func (d *Blocker) Blockit() <-chan bool {
connected := make(chan bool)

go func() {
for {
err := d.db.Ping()
if err != nil {
<-time.After(1 * time.Second)
continue
}

connected <- true
close(connected)

break
}
}()

return connected
func New(db *sql.DB) *cbblocker.Blocker {
return cbblocker.New(db.Ping, 1*time.Second)
}

0 comments on commit 3b76a9e

Please sign in to comment.