Last active
August 21, 2016 15:38
-
-
Save RichyHBM/f22f873635a044549b5cbeb6449f82f6 to your computer and use it in GitHub Desktop.
Simple goroutines wrapper to provide Scala-like futures functionality in Golang. Adapted from: http://labs.strava.com/blog/futures-in-golang/
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 ( | |
"errors" | |
"time" | |
) | |
type FutureFunction func() (interface{}, error) | |
type FutureResult func(timeout ...time.Duration) (interface{}, error) | |
func Future(f FutureFunction) FutureResult { | |
var result interface{} | |
var err error | |
c := make(chan struct{}, 1) | |
go func() { | |
defer close(c) | |
result, err = f() | |
}() | |
return func(timeout ...time.Duration) (interface{}, error) { | |
if len(timeout) == 1 { | |
select { | |
case <-c: | |
return result, err | |
case <-time.After(timeout[0]): | |
return nil, errors.New("Future timeout") | |
} | |
} else { | |
<-c | |
return result, err | |
} | |
} | |
} |
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 ( | |
"fmt" | |
"time" | |
) | |
func DoLongProcessing() (interface{}, error) { | |
time.Sleep(time.Second * 5) | |
return 123, nil | |
} | |
func printResults(res interface{}, err error, start time.Duration, waiting time.Duration) { | |
if err != nil { | |
fmt.Printf("Error: '%s', %v since start, total wait time for this function: %v\n", err, start, waiting) | |
} else { | |
fmt.Printf("Success: '%d', %v since start, total wait time for this function: %v\n", res, start, waiting) | |
} | |
} | |
func main() { | |
start := time.Now() | |
future := Future(DoLongProcessing) | |
waiting := time.Now() | |
var res, err = future(time.Millisecond * 500) | |
printResults(res, err, time.Since(start), time.Since(waiting)) | |
waiting = time.Now() | |
res, err = future() | |
printResults(res, err, time.Since(start), time.Since(waiting)) | |
waiting = time.Now() | |
res, err = future() | |
printResults(res, err, time.Since(start), time.Since(waiting)) | |
} |
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
> go run .\main.go .\futures.go | |
Error: 'Future timeout', 500.1081ms since start, total wait time for this function: 500.1081ms | |
Success: '123', 5.0002842s since start, total wait time for this function: 4.5001761s | |
Success: '123', 5.0002842s since start, total wait time for this function: 0s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment