Skip to content

Instantly share code, notes, and snippets.

@arielsrv
Created October 18, 2022 09:31
Show Gist options
  • Save arielsrv/64ae0fae1a435e3de8112e2367fd2c12 to your computer and use it in GitHub Desktop.
Save arielsrv/64ae0fae1a435e3de8112e2367fd2c12 to your computer and use it in GitHub Desktop.
rest_concept_concurrency
package main
import (
"container/list"
"fmt"
"github.com/tjarratt/babble"
"sync"
"sync/atomic"
"time"
"unsafe"
)
func main() {
builder := NewRequestBuilder()
// Blocking
response := builder.Get()
fmt.Printf("Get(): %s\n", response.Body)
// Futures blocking
var futures [5]*FutureResponse
builder.ForkJoin(func(c *Concurrent) {
futures[0] = c.Get()
futures[1] = c.Get()
futures[2] = c.Get()
futures[3] = c.Get()
futures[4] = c.Get()
})
for i := range futures {
fmt.Printf("ForkJoin(%d): %s\n", i, futures[i].Response().Body)
}
// Non-blocking
builder.AsyncGet(func(r *Response) {
fmt.Printf("AsyncGet(): %s", r.Body)
})
time.Sleep(time.Millisecond * 50)
}
type RequestBuilder struct {
babbler babble.Babbler
}
func NewRequestBuilder() *RequestBuilder {
return &RequestBuilder{babbler: babble.NewBabbler()}
}
func (rb *RequestBuilder) Get() *Response {
return &Response{Body: rb.babbler.Babble()}
}
func (rb *RequestBuilder) AsyncGet(f func(*Response)) {
go f(rb.Get())
}
type Response struct {
Body string
}
func (rb *RequestBuilder) ForkJoin(f func(*Concurrent)) {
c := new(Concurrent)
c.requestBuilder = rb
f(c)
c.wg.Add(c.list.Len())
for node := c.list.Front(); node != nil; node = node.Next() {
go node.Value.(func())()
}
c.wg.Wait()
}
type Concurrent struct {
list list.List
wg sync.WaitGroup
requestBuilder *RequestBuilder
}
func (c *Concurrent) Get() *FutureResponse {
fr := new(FutureResponse)
future := func() {
defer c.wg.Done()
message := c.requestBuilder.Get()
atomic.StorePointer(&fr.pointer, unsafe.Pointer(message))
}
c.list.PushBack(future)
return fr
}
type FutureResponse struct {
pointer unsafe.Pointer
}
func (fr *FutureResponse) Response() *Response {
return (*Response)(fr.pointer)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment