Created
November 20, 2015 13:05
-
-
Save iamralch/cfaddf955091d50c93aa to your computer and use it in GitHub Desktop.
An example that illustrates how to work with https://godoc.org/golang.org/x/net/context
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"fmt" | |
"os" | |
"strings" | |
"time" | |
"golang.org/x/net/context" | |
) | |
type Payment struct { | |
Payee string | |
Amount float64 | |
} | |
func ProcessPayment(ctx context.Context, payment *Payment) { | |
confirmed := ctx.Value("confirmed").(chan struct{}) | |
for { | |
select { | |
case <-confirmed: | |
fmt.Printf("Your payment of %f GBP has been completed succefully.\n", payment.Amount) | |
return | |
case <-ctx.Done(): | |
if ctx.Err() == context.Canceled { | |
fmt.Printf("Your payment transaction is canceled. The amount of %f GBP has been refunded.\n", payment.Amount) | |
return | |
} else if ctx.Err() == context.DeadlineExceeded { | |
fmt.Println("Your payment transaction expired. You can complete it later.") | |
os.Exit(0) | |
} | |
default: | |
time.Sleep(1 * time.Second) | |
} | |
} | |
} | |
func main() { | |
var ( | |
ctx context.Context | |
cancel context.CancelFunc | |
) | |
confirmed := make(chan struct{}) | |
ctx = context.WithValue(context.Background(), "confirmed", confirmed) | |
ctx, cancel = context.WithTimeout(ctx, 1*time.Minute) | |
go ProcessPayment(ctx, &Payment{ | |
Payee: "John Doe", | |
Amount: 128.54}) | |
fmt.Print("Your payment transaction is pending. ") | |
if deadline, ok := ctx.Deadline(); ok { | |
fmt.Printf("You have %s to complete the payment.\n", deadline.Sub(time.Now()).String()) | |
} | |
fmt.Println() | |
fmt.Println("Please choose one of the following options:") | |
reader := bufio.NewReader(os.Stdin) | |
for { | |
fmt.Printf("[C]onfirm, (A)bort: ") | |
if line, err := reader.ReadString('\n'); err == nil { | |
command := strings.TrimSuffix(line, "\n") | |
switch command { | |
case "C": | |
confirmed <- struct{}{} | |
time.Sleep(500 * time.Millisecond) | |
return | |
case "A": | |
cancel() | |
time.Sleep(500 * time.Millisecond) | |
return | |
default: | |
fmt.Printf("\nWrong option: %s. Please try again.\n", command) | |
fmt.Println("Please confirm your transaction:") | |
} | |
} | |
} | |
} |
for future reference, questions 1 & 2 refer to type casting, since what you are getting from the Context.value cannot be determined on compile time, a good example https://golang.org/doc/effective_go.html#blank_implements
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@Svett thank you for the context example. I have some questions. Maybe you can explain it :)
1.) What exactly does this line do? https://gist.github.com/svett/cfaddf955091d50c93aa#file-context-go-L19 ... i know that is a Type assertions but what it do in this scenario?
2.) It is possible to resolve https://gist.github.com/svett/cfaddf955091d50c93aa#file-context-go-L19 differently? Without type assertion! It that maybe a shortform for?!?
3.) Maybe you fully comment you code?
I hope you can help me :)