Skip to content

Latest commit

 

History

History
135 lines (95 loc) · 5.75 KB

UPDATING.md

File metadata and controls

135 lines (95 loc) · 5.75 KB

Upgrade / Migration Guide

Version 1.1.5 to 1.2.0

We have made many breaking changes in the version 1.2 release of this SDK.

In this guide we aim to highlight the main differences you will encounter when migrating your code from the interfaces we were offering prior to the version 1.2.0 release.

These include:

Asynchronous Operations and the Context Concurrency Pattern

We've now moved to a model where methods are blocking in nature, cancellable with a Context.

We use ctx in examples to refer to a Context instance that you create in your code.

For robust, production-ready applications you will rarely (actually, probably never) want to create your Context using the basic Background function, because it cannot be cancelled and remains for the lifecycle of the program. Instead, you should use WithTimeout or WithDeadline.

For example, a context can be created with a 10-second timeout like this:

context.WithTimeout(context.Background(), 10 * time.Second)

Adding the necessary code to stay on top of cancellation, you will need something like this:

ctx, cancel := context.WithTimeout(context.Background(), 10 * time.Second)
defer cancel()

This way, the context can be cancelled at the close of the function.

Note: For Realtime operations, cancellation isn't supported by the underlying protocol. A context cancellation in this case just means that the call returns immediately, without waiting for the operation to finish, with the error provided by the context; but the operation carries on in the background. Timeouts for these operations are handled separately, with a configurable realtime request timeout duration.

Client Options now has a Functional Interface

Before version 1.2.0, you instantiated a client using a ClientOptions instance created with the NewClientOptions function:

client, err := ably.NewRealtime(ably.NewClientOptions("xxx:xxx"))

Starting with version 1.2.0, you must use the new functional interface:

client, err := ably.NewRealtime(ably.WithKey("xxx:xxx"))

For a full list of client options, see all functions prefixed by With that return a ClientOption function in the API reference.

Subscription now uses Message Handlers

Before version 1.2.0, you subscribed to receive all messages from a Go channel like this:

sub, _ := channel.Subscribe()
for msg := range sub.MessageChannel() {
    fmt.Println("Received message: ", msg)
}

Starting with version 1.2.0, you must supply a context and your own message handler function to the new SubscribeAll method:

unsubscribe, _ := channel.SubscribeAll(ctx, func(msg *ably.Message) {
    fmt.Println("Received message: ", msg)
})

The signature of the Subscribe method has also changed. It now requires a Context as well as the channel name and your message handler.

Both Subscribe and SubscribeAll are now blocking methods.

Detail around the concurrency and routing of calls to message and event handlers is described in the package documentation under Event Emitters.

The Publish Method now Blocks

Before version 1.2.0, you published messages to a channel by calling the Publish method and then waiting for the Result:

result, _ := channel.Publish("EventName1", "EventData1")

// block until the publish operation completes
result.Wait()

Starting with version 1.2.0, you must supply a context, as this method is now blocking:

// block until the publish operation completes or is cancelled
err := channel.Publish(ctx, "EventName1", "EventData1")

Querying History

Before version 1.2.0, you queried history as shown below, receiving a PaginatedResult from the History function:

page, err := channel.History(nil)
for ; err == nil; page, err = page.Next() {
    for _, message := range page.Messages() {
        fmt.Println("Message from History: ", message)
    }
}
if err != nil {
    panic(err)
}

Starting with version 1.2.0, you must first call History, which can be passed functional options, and then use the Pages (or Items, if you prefer) method on the returned HistoryRequest instance

pages, err := channel.History().Pages(ctx)
if err != nil {
    panic(err)
}
for pages.Next(ctx) {
    for _, message := range pages.Items() {
        fmt.Println("Message from History: ", message)
    }
}
if err := pages.Err(); err != nil {
    panic(err)
}