-
Notifications
You must be signed in to change notification settings - Fork 10
Adding support for context.Context #9
Conversation
} | ||
|
||
// TODO: how can we check if a store has been opened...? | ||
type storeWrapper struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add a "opened" property here, if required.
for n := i - 1; n >= 0; n-- { | ||
c.stores[n].Put(key, val) // errors..? | ||
} | ||
nextStore := make(chan Store, len(c.stores)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @VojtechVitek,
I had to modify your snippet a bit, what do you think of the new location of the range over putBack
? Otherwise it just stays blocked waiting for a value to arrive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did it block because the channel was unbuffered?
putBack := make(chan Store, len(c.stores))
shouldn't block, I can't imagine how.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Taking that back ... obviously not, let me see the code again :) I was throwing it of top of my head. But this looks good already :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, I have a working snippet for you... without firstVal channel and the extra goroutine:
package main
import (
"errors"
"fmt"
"time"
"golang.org/x/net/context"
)
func Get(ctx context.Context) (string, error) {
nextStore := make(chan string, 3)
for _, store := range []string{"first", "second", "third"} {
nextStore <- store
}
close(nextStore)
putBack := make(chan string, 3)
for {
select {
case <-ctx.Done():
return "", ctx.Err()
case store, ok := <-nextStore:
if !ok {
return "", errors.New("not found")
}
if store != "fourth" { // change this --- simulating what store returns FOUND
putBack <- store
break
}
close(putBack)
for store := range putBack {
go fmt.Printf("putting back to %v store\n", store)
}
return fmt.Sprintf("found in %v", store), nil
}
}
panic("unreachable")
}
func main() {
ctx, _ := context.WithTimeout(context.Background(), time.Second)
val, err := Get(ctx)
fmt.Println(val, err)
// wait for fmt.Printf() from goroutines
time.Sleep(time.Second)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! makes sense, the close(putBack)
is what makes the range not to lock. I like it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried closing the channel and everything worked fine :).
All right, I also updated all the other stores, their tests and the example. Now everything is working as before. |
LGTM :) @xiam can you add document changing the |
…ncel(context.Background()).
…emove that nil key from our tests.
Adding support for context.Context
Hey @pkieltyka,
This work in progress features code changes for chainstore and a new
mockstore
store that I'm using to test the chainstore withcontext.Context
. The intention of this PR is to review the code changes in chainstore and see if we can start updating the other stores to reflect changes in the interface.See: #8