Documentation ¶
Overview ¶
A true (persistently connected and stateful) Simperium client
Example Simperium client code:
package main import ( "github.com/apokalyptik/go-simperium" "log" ) var isReady chan bool func onReady(bucket string) { isReady <- true } func main() { wait := make(chan struct{}) isReady = make(chan bool, 1) simperium := new(simperium.Client) simperium.SetDebug(true) testBucket, err := simperium.Bucket(myAppID, myBucketName, myApiKey) if err != nil { log.Fatal(err) } testBucket.OnReady(onReady) testBucket.Start() <-isReady sendDoc := map[string]interface{}{ "someString": "one two three four", "someNumbers": []int{1, 2, 3, 4}, "oneNumber": 1, "oneDict": map[string]interface{}{"one": 1}, "someDicts": []map[string]interface{}{{"two": 2}, {"three": 3}}} testBucket.Update("document-id", sendDoc) <-wait }
Index ¶
- Variables
- type Bucket
- func (b *Bucket) MindOutgoingChanges()
- func (b *Bucket) OnError(f ErrorFunc)
- func (b *Bucket) OnNotify(f NotifyFunc)
- func (b *Bucket) OnNotifyInit(f NotifyFunc)
- func (b *Bucket) OnReady(f ReadyFunc)
- func (b *Bucket) OnStarting(f ReadyFunc)
- func (b *Bucket) SetDebug(debug bool)
- func (b *Bucket) Start()
- func (b *Bucket) Update(documentId string, data map[string]interface{}) error
- type Client
- type ErrorFunc
- type NotifyFunc
- type ReadyFunc
- Bugs
Constants ¶
This section is empty.
Variables ¶
var BadServerResponse error = errors.New("Simperium gave an unexpected response")
var ErrorAuthFail error = errors.New("Authorization Failed")
Functions ¶
This section is empty.
Types ¶
type Bucket ¶
type Bucket struct {
// contains filtered or unexported fields
}
func (*Bucket) MindOutgoingChanges ¶
func (b *Bucket) MindOutgoingChanges()
Create a goroutine minding outgoing changes for the bucket. Each gorouting sends exactly one change, then waits for it to be accepete by Simperium. It then accepts one more change (wash, rinse, repeat.) By default one of these is created. More of these goroutines means better concurrency, but as the number of these increases there are tradeoffs. First there will be more memory used to keep more changes in memory until they're processed and accepted. Second there will be more resources used watching the pending changes queue for their changes to be removed. Finally You run the risk of being rate limited by the simperium service for having too many pending changes (when this happens simperium sends error:503 and the bucket client will retry until it succeeds, causing these routines to wait longer and block longer) Obviously more is better... until it's not.
func (*Bucket) OnError ¶
Specify whch function to use as a callback for when an error is encountered with bucket operations
func (*Bucket) OnNotify ¶
func (b *Bucket) OnNotify(f NotifyFunc)
Specify which function to use as a callback after the startup phase of the bucket to notify you of existing documents and their data
func (*Bucket) OnNotifyInit ¶
func (b *Bucket) OnNotifyInit(f NotifyFunc)
Specify which function to use as a callback during the startup phase of the bucket to notify you of existing documents and their data
func (*Bucket) OnReady ¶
Specify which function to use as a callback to let you know that the startup phase of the bucket has finished and the Bucket structure is up, and syncing
func (*Bucket) OnStarting ¶
Specify which function to use as a callback to let you know that the bucket is beginning its startup phase. This can happen the first time Start() is called or after a client reconnect in which case expect notify-init and ready callbacks to come through notifying you of the buckets current contents which will include and supercede anything existing. It's recommended that you flush your application state for the bucket and rebuild it anew at this point for the sake of consistency
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
A client connection to simperium. One persistent websocket connection is maintained via this parent structure. The child structures (Buckets) communicate through this to talk to simperium via websocket channels. Each channel (and thus bucket) is authenticated individually which is why no app/bucket/token is needed when creating this structure.
func (*Client) Bucket ¶
Instantiate a connection to a Simperium Bucket communicating through a new channel on this clients existing websocket connection
func (*Client) SetHeartbeat ¶
type ErrorFunc ¶
The function signature for the OnError callback.
func Handler(bucket string, err error) {...}
type NotifyFunc ¶
The function signature for the OnNotify and OnNotifyInit callbacks
func Handler(bucket, documentId string, data map[string]interface{}) {...}
Notes ¶
Bugs ¶
Bucket -- On reconnect it would be better to list all changes since our last known change and process them appropriately
Bucket -- Need to process options messages which are sent after successful authentication
Bucket -- Need to handle a number of "error": xxx messages that the server could return (some of which aren't "errors", like the duplicate change error)
Client -- We may lose a write in this recover. Need to see if we can get a message into c.writeQueue from here