Created
January 26, 2022 18:33
-
-
Save geoah/f559bfbfd1feedb82cceba7bff6bd66a to your computer and use it in GitHub Desktop.
go1.18-eventsource-poc-v0
This file contains hidden or 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 stream | |
import ( | |
"fmt" | |
"nimona.io/pkg/object" | |
) | |
type ( | |
Applicable[State any] interface { | |
Apply(*State) error | |
} | |
Controller[State any] interface { | |
NewStream() Stream[State] | |
} | |
Stream[State any] interface { | |
ApplyObject(*object.Object) error | |
ApplyEvent(Applicable[State]) error | |
GetState() State | |
} | |
controller[State any] struct{} | |
stream[State any] struct { | |
// lock sync.RWMutex // TODO add mutex | |
LatestState *State | |
} | |
) | |
func NewController[State any]() Controller[State] { | |
c := &controller[State]{} | |
return c | |
} | |
func (c *controller[State]) NewStream() Stream[State] { | |
s := &stream[State]{ | |
LatestState: new(State), | |
} | |
return s | |
} | |
func (s *stream[State]) ApplyObject(o *object.Object) error { | |
return nil | |
} | |
func (s *stream[State]) ApplyEvent(e Applicable[State]) error { | |
err := e.Apply(s.LatestState) | |
if err != nil { | |
return fmt.Errorf("error applying state, %w", err) | |
} | |
return nil | |
} | |
func (s *stream[State]) GetState() State { | |
return *s.LatestState | |
} |
This file contains hidden or 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 stream | |
import ( | |
"testing" | |
"github.com/stretchr/testify/require" | |
"nimona.io/pkg/object" | |
) | |
type ( | |
TestState struct { | |
Foo int | |
Bar int | |
Comments []string | |
} | |
TestEventAddFoo struct { | |
Metadata object.Metadata | |
} | |
TestEventAddBar struct { | |
Metadata object.Metadata | |
} | |
TestEventAddComment struct { | |
Metadata object.Metadata | |
Comment string | |
} | |
) | |
func (e *TestEventAddFoo) Apply(s *TestState) error { | |
s.Foo++ | |
return nil | |
} | |
func (e *TestEventAddBar) Apply(s *TestState) error { | |
s.Bar++ | |
return nil | |
} | |
func (e *TestEventAddComment) Apply(s *TestState) error { | |
s.Comments = append(s.Comments, e.Comment) | |
return nil | |
} | |
func Test_Controller_Example(t *testing.T) { | |
c := NewController[TestState]() | |
require.NotNil(t, c) | |
s := c.NewStream() | |
err := s.ApplyEvent(&TestEventAddFoo{}) | |
require.NoError(t, err) | |
err = s.ApplyEvent(&TestEventAddFoo{}) | |
require.NoError(t, err) | |
err = s.ApplyEvent(&TestEventAddBar{}) | |
require.NoError(t, err) | |
err = s.ApplyEvent(&TestEventAddComment{Comment: "hello"}) | |
require.NoError(t, err) | |
err = s.ApplyEvent(&TestEventAddComment{Comment: "world"}) | |
require.NoError(t, err) | |
require.Equal(t, TestState{ | |
Foo: 2, | |
Bar: 1, | |
Comments: []string{ | |
"hello", | |
"world", | |
}, | |
}, s.GetState()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment