Go client library SDK for Ably realtime messaging service

Overview

Ably Go

A Go client library for www.ably.io, the realtime messaging service.

Installation

~ $ go get -u github.com/ably/ably-go/ably

Feature support

This library implements the Ably REST and Realtime client APIs.

REST API

In respect of the Ably REST API, this library targets the Ably 1.1 client library specification, with some omissions as follows (see the client library specification for specification references):

Feature
Push notifications admin API
JWT authentication

It is intended that this library is upgraded incrementally, with 1.1 feature support expanded in successive minor releases. If there are features that are currently missing that are a high priority for your use-case then please contact Ably customer support. Pull Requests are also welcomed.

Realtime API

In respect of the Realtime API, this is an early experimental implementation that targets the (now superseded) 0.8 library specification. This means that there are significant shortfalls in functionality; the principal issues are:

  • there is no channel suspended state; this means that the client will not automatically reattach to channels if a connection becomes suspended and then resumes, and presence members associated with the client will not be automatically re-entered;

  • transient realtime publishing is not supported, so a call to publish() on a realtime channel will trigger attachment of the channel;

  • inband reauthentication is not supported; expiring tokens will trigger a disconnection and resume of a realtime connection.

As with the REST API, it is intended that this library is upgraded incrementally and brought into line with the 1.1 specification. If there are features that are currently missing that are a high priority for your use-case then please contact Ably customer support. Pull Requests are also welcomed.

Using the Realtime API

Creating a client

client, err := ably.NewRealtimeClient(ably.NewClientOptions("xxx:xxx"))
if err != nil {
	panic(err)
}

channel := client.Channels.Get("test")

Subscribing to a channel for all events

sub, err := channel.Subscribe()
if err != nil {
	panic(err)
}

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

Subscribing to a channel for EventName1 and EventName2 events

sub, err := channel.Subscribe("EventName1", "EventName2")
if err != nil {
	panic(err)
}

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

Publishing to a channel

// send request to a server
res, err := channel.Publish("EventName1", "EventData1")
if err != nil {
	panic(err)
}

// await confirmation
if err = res.Wait(); err != nil {
	panic(err)
}

Announcing presence on a channel

// send request to a server
res, err := channel.Presence.Enter("presence data")
if err != nil {
	panic(err)
}

// await confirmation
if err = res.Wait(); err != nil {
	panic(err)
}

Announcing presence on a channel on behalf of other client

// send request to a server
res, err := channel.Presence.EnterClient("clientID", "presence data")
if err != nil {
	panic(err)
}

// await confirmation
if err = res.Wait(); err != nil {
	panic(err)
}

Getting all clients present on a channel

clients, err := channel.Presence.Get(true)
if err != nil {
	panic(err)
}

for _, client := range clients {
	fmt.Println("Present client:", client)
}

Subscribing to all presence messages

sub, err := channel.Presence.Subscribe()
if err != nil {
	panic(err)
}

for msg := range sub.PresenceChannel() {
	fmt.Println("Presence event:", msg)
}

Subscribing to 'Enter' presence messages only

sub, err := channel.Presence.Subscribe(proto.PresenceEnter)
if err != nil {
	panic(err)
}

for msg := range sub.PresenceChannel() {
	fmt.Println("Presence event:", msg)
}

Using the REST API

Introduction

All examples assume a client and/or channel has been created as follows:

client, err := ably.NewRestClient(ably.NewClientOptions("xxx:xxx"))
if err != nil {
	panic(err)
}

channel := client.Channels.Get("test", nil)

Publishing a message to a channel

err = channel.Publish("HelloEvent", "Hello!")
if err != nil {
	panic(err)
}

Querying the History

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

Presence on a channel

page, err := channel.Presence.Get(nil)
for ; err == nil; page, err = page.Next() {
	for _, presence := range page.PresenceMessages() {
		fmt.Println(presence)
	}
}
if err != nil {
	panic(err)
}

Querying the Presence History

page, err := channel.Presence.History(nil)
for ; err == nil; page, err = page.Next() {
	for _, presence := range page.PresenceMessages() {
		fmt.Println(presence)
	}
}
if err != nil {
	panic(err)
}

Generate Token and Token Request

client.Auth.RequestToken()
client.Auth.CreateTokenRequest()

Fetching your application's stats

page, err := client.Stats(&ably.PaginateParams{})
for ; err == nil; page, err = page.Next() {
	for _, stat := range page.Stats() {
		fmt.Println(stat)
	}
}
if err != nil {
	panic(err)
}

Known limitations (work in progress)

As the library is actively developed couple of features are not there yet:

  • Realtime connection recovery is not implemented
  • Realtime connection failure handling is not implemented
  • ChannelsOptions and CipherParams are not supported when creating a Channel
  • Realtime Ping function is not implemented

Release process

This library uses semantic versioning. For each release, the following needs to be done:

  • Create a branch for the release, named like release/1.1.6
  • Replace all references of the current version number with the new version number and commit the changes
  • Run github_changelog_generator to automate the update of the CHANGELOG. This may require some manual intervention, both in terms of how the command is run and how the change log file is modified. Your mileage may vary:
    • The command you will need to run will look something like this: github_changelog_generator -u ably -p ably-go --since-tag v1.1.4 --output delta.md
    • Using the command above, --output delta.md writes changes made after --since-tag to a new file
    • The contents of that new file (delta.md) then need to be manually inserted at the top of the CHANGELOG.md, changing the "Unreleased" heading and linking with the current version numbers
    • Also ensure that the "Full Changelog" link points to the new version tag instead of the HEAD
    • Commit this change: git add CHANGELOG.md && git commit -m "Update change log."
  • Commit CHANGELOG
  • Make a PR against main
  • Once the PR is approved, merge it into main
  • Add a tag to the new main head commit and push to origin such as git tag v1.1.6 && git push origin v1.1.6

Support and feedback

Please visit http://support.ably.io/ for access to our knowledgebase and to ask for any assistance.

You can also view the community reported Github issues.

Contributing

Because this package uses internal packages, all fork development has to happen under $GOPATH/src/github.com/ably/ably-go to prevent use of internal package not allowed errors.

  1. Fork github.com/ably/ably-go
  2. go to the ably-go directory: cd $GOPATH/src/github.com/ably/ably-go
  3. add your fork as a remote: git remote add fork [email protected]:your-username/ably-go
  4. create your feature branch: git checkout -b my-new-feature
  5. commit your changes (git commit -am 'Add some feature')
  6. ensure you have added suitable tests and the test suite is passing for both JSON and MessagePack protocols by running scripts/test.sh.
  7. push to the branch: git push fork my-new-feature
  8. create a new Pull Request
Issues
  • Replace obsolete websocket library -- allows WebAssembly

    Replace obsolete websocket library -- allows WebAssembly

    This replaces the unmaintained golang.org/x/net/websocket websocket library with nhooyr.io/websocket. This allows compiling go-ably to WebAssembly and using Ably from a browser.

    resolves #368

    opened by Jmgr 14
  • Add connection key to messages.

    Add connection key to messages.

    This fixes #442 a customer previously raised a PR to add ConnectionKey to the message. However the value of this new connection key field was never populated, so it still was not possible for a rest client to publish on behalf of a realtime client. This PR populates the connection key when rest messages are published.

    opened by Rosalita 12
  • Bugfix: REST publish encoding was

    Bugfix: REST publish encoding was "utf8" should be "utf-8"

    There was an error which prevented me from running tests and vetting the application. The package name "internal" is not valid and Go v1.8 complains. I've moved the package up 1 directory so instead of /ably/internal/ablyutil it's /ably/ablyutil.

    I've also fixed the encoding which is being set when publishing a REST message. The clients and everywhere else in the library use "utf-8" as the encoding, but this was using "utf8" which was causing an encoding error on the client when trying to decode the message.

    bug question 
    opened by CraigChilds94 12
  • Structure change

    Structure change

    @lmars Would you mind taking a look into this?

    To keep things more or less consistent with other libraries, I had to find a way to have an equivalent of Ably::Rest::Client.new() or new Ably.Rest.Client(). So I created a struct in the ably namespace for Rest which doesn't do anything special apart from being a fake sub-package and allow me to call ably.Rest.NewClient().

    We could accept that people will call rest.Client like we did in most tests but I don't think that it conveys the right meaning (it's an ably client, not just an HTTP client). Unless you think we should advise to rename package on import (import ably "github.com/ably/ably-go"), but again I don't think it's conventional.

    Thoughts?

    opened by kouno 12
  • v1.2 API design

    v1.2 API design

    This issue tracks and discuss the changes to be made to the public API in order to make it 1.2 spec-compliant.

    Subscriptions: from channels to callbacks

    For some features, we make a long-lived subscription to a series of events that the caller receives. The spec says those events are delivered by calling a callback. In Go, instead, we were sending them to channels, from which user code receive events at their own. For 1.2 we're taking callbacks. See the relevant discussion.

    So we go from something like:

    ch := make(chan ably.ChannelStateChange)
    channel.On(ably.ChannelStateChange, ably.ConnectionEventAttached)
    for change := range ch {
        // ...
    }
    

    To:

    channel.On(ably.ConnectionEventAttached, func(change ably.ChannelStateChange) {
        // ...
    })
    

    The list of such features is:

    • [x] Connection events (#144)
    • [x] Channel events (#190)
    • [x] Messages (#202)
    • [x] Pressence messages (#202)

    Options

    We've decided to implement the classes from the spec that define options as functional options instead.

    Each option is defined as a package-level function, with a With prefix. Additionally, except ClientOptions, each function has first the name of what they're options for as prefix (e. g. RestChannel.publish(params?)PublishBatchWithParams). (Discussion below.)

    • [x] ClientOptions and AuthOptions (#145)
      • [x] Converted to package-level functions (#205).
    • [x] ChannelOptions (#146)
      • [x] Converted to package-level functions (#205).

    Optional arguments

    Optional arguments are translated as functional options, as described above. (Discussion below.)

    If an optional argument is itself an options aggregate per the spec, the options "collapse" into a single level.

    io actions: from Result to blocking calls

    The spec marks with a io annotation values that result from making an IO operation (to the network, typically). In some environments (JavaScript, Cocoa) those are implemented by passing them to a callback or an equivalent Promise-style mechanism. In others, it's just a normal function call that blocks until the operation is complete and returns the value. If the user wants to do more than one thing at once, they use threads or some equivalent.

    In Go, it's common-place to do the latter: calls that hit the network block for the whole duration, and if you want asynchrony, you spawn goroutines. But we're using a two-stage Promise-like thing in which a method first initiates the operation on the background and returns (ably.Result, error) immediately; then, you can call ably.Result.Wait() to wait for the operation to complete, which may produce.

    This is weird for Go (see #155) and we're switching to fully blocking calls for the duration of the operation.

    So this:

    result, err := channel.Attach()
    if err != nil {
        // ...
    }
    err = result.Wait()
    if err != nil {
        // ...
    }
    

    Becomes:

    err := channel.Attach()
    if err != nil {
        // ...
    }
    

    Context

    In Go, it has become common-place for IO operations to take a context.Context. For 1.2, we will implement the io annotation by adding a first context.Context argument in such methods.

    For HTTP requests, the context is passed in the underlying *http.Request.

    For operations that result in WebSocket sends and receives, the situation is a bit more complex. A WebSocket is ultimately a net.Conn, which is just a io.Reader and io.Writer; those don't take contexts. So the context would only be used to unblock the call at the point it's waiting for a WebSocket receive, e. g. an ATTACHED message.

    This raises the question: do we then act as if the operation has failed entirely? E. g. do we go back to the INITIALIZED/DETACHED state from ATTACHING?

    1. If we do, then the client and the server may disagree on the channel state. Normally, this possible discrepancy is resolved because the connection is broken and reestablished after a receive timeout or some other network condition that causes the error.

    2. If we don't, then we cause the surprising effect that the operation returns an error, yet we see the consequences of success anyway, e. g. start receiving messages on the channel.

    3. Another possibility is not taking contexts at all for WebSocket operations, but that seems inconsistent.

    I'd say we can go with 2 and just implement a transparent way of dealing with the inconsistency, e. g. automatically detach once the ATTACHED arrives. This should be in the spec too.

    Misc: names, argument order, etc.

    The rest would just be straightforward: make sure we expose only the API from the spec, in the form and shape in which the spec defines it. This includes renaming, removing things or moving them to separate packages, reordering arguments, etc.

    spec-alignment 
    opened by tcard 11
  • Client appears to be leaking TCP connections/file descriptors

    Client appears to be leaking TCP connections/file descriptors

    We have some code in our service that is doing this:

    import (
    	"github.com/ably/ably-go/ably"
    )
    
    msg := "..."
    client := ably.NewRestClient(ably.NewClientOptions(apiKey))
    
    if err := client.Channel("private:some-channel").Publish("data_ready", string(msg)); err != nil {
    	return err
    }
    

    We are using revision 0cadbda3606928bcf94acc34cb9cc9ca0b9511ac of the ably-go client.

    When this runs, the service starts to leak a large number of TCP connections to Ably's rest.ably.io load balancer. Here's the output of lsof -p {service pid} after a few seconds of running:

    COMMAND   PID   USER   FD      TYPE   DEVICE SIZE/OFF     NODE NAME
    {service} 27085 {user}   14u     IPv4 42056111      0t0      TCP ip-10-0-2-94.ec2.internal:43861->ec2-52-0-70-16.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   15u     IPv4 42057076      0t0      TCP ip-10-0-2-94.ec2.internal:46022->ec2-52-207-88-5.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   16u     IPv4 42057083      0t0      TCP ip-10-0-2-94.ec2.internal:43913->ec2-52-0-70-16.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   17u     IPv4 42056169      0t0      TCP ip-10-0-2-94.ec2.internal:46034->ec2-52-207-88-5.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   18u     IPv4 42057114      0t0      TCP ip-10-0-2-94.ec2.internal:43933->ec2-52-0-70-16.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   19u     IPv4 42057151      0t0      TCP ip-10-0-2-94.ec2.internal:43959->ec2-52-0-70-16.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   20u     IPv4 42057127      0t0      TCP ip-10-0-2-94.ec2.internal:20860->ec2-52-20-107-126.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   21u     IPv4 42056184      0t0      TCP ip-10-0-2-94.ec2.internal:46050->ec2-52-207-88-5.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   22u     IPv4 42056206      0t0      TCP ip-10-0-2-94.ec2.internal:46078->ec2-52-207-88-5.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   23u     IPv4 42056216      0t0      TCP ip-10-0-2-94.ec2.internal:43975->ec2-52-0-70-16.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   24u     IPv4 42056233      0t0      TCP ip-10-0-2-94.ec2.internal:46102->ec2-52-207-88-5.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   25u     IPv4 42056248      0t0      TCP ip-10-0-2-94.ec2.internal:44005->ec2-52-0-70-16.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   26u     IPv4 42057212      0t0      TCP ip-10-0-2-94.ec2.internal:46128->ec2-52-207-88-5.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   28u     IPv4 42056281      0t0      TCP ip-10-0-2-94.ec2.internal:44039->ec2-52-0-70-16.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   29u     IPv4 42056288      0t0      TCP ip-10-0-2-94.ec2.internal:46156->ec2-52-207-88-5.compute-1.amazonaws.com:https (ESTABLISHED)
    

    Eventually the connections enter a CLOSE_WAIT state, but still persist:

    COMMAND   PID   USER   FD      TYPE   DEVICE SIZE/OFF     NODE NAME
    {service} 27085 {user}   12u     IPv4 42056997      0t0      TCP ip-10-0-2-94.ec2.internal:45966->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   13u     IPv4 42057706      0t0      TCP ip-10-0-2-94.ec2.internal:44331->ec2-52-0-70-16.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   14u     IPv4 42056111      0t0      TCP ip-10-0-2-94.ec2.internal:43861->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   15u     IPv4 42057076      0t0      TCP ip-10-0-2-94.ec2.internal:46022->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   16u     IPv4 42057083      0t0      TCP ip-10-0-2-94.ec2.internal:43913->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   17u     IPv4 42056169      0t0      TCP ip-10-0-2-94.ec2.internal:46034->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   18u     IPv4 42057114      0t0      TCP ip-10-0-2-94.ec2.internal:43933->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   19u     IPv4 42057151      0t0      TCP ip-10-0-2-94.ec2.internal:43959->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   20u     IPv4 42057127      0t0      TCP ip-10-0-2-94.ec2.internal:20860->ec2-52-20-107-126.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   21u     IPv4 42056184      0t0      TCP ip-10-0-2-94.ec2.internal:46050->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   22u     IPv4 42056206      0t0      TCP ip-10-0-2-94.ec2.internal:46078->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   23u     IPv4 42056216      0t0      TCP ip-10-0-2-94.ec2.internal:43975->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   24u     IPv4 42056233      0t0      TCP ip-10-0-2-94.ec2.internal:46102->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   25u     IPv4 42056248      0t0      TCP ip-10-0-2-94.ec2.internal:44005->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   26u     IPv4 42057212      0t0      TCP ip-10-0-2-94.ec2.internal:46128->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   27u     IPv4 42056339      0t0      TCP ip-10-0-2-94.ec2.internal:44057->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   28u     IPv4 42056281      0t0      TCP ip-10-0-2-94.ec2.internal:44039->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   29u     IPv4 42056288      0t0      TCP ip-10-0-2-94.ec2.internal:46156->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   30u     IPv4 42057383      0t0      TCP ip-10-0-2-94.ec2.internal:46186->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   31u     IPv4 42056381      0t0      TCP ip-10-0-2-94.ec2.internal:44093->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   32u     IPv4 42057433      0t0      TCP ip-10-0-2-94.ec2.internal:46226->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   33u     IPv4 42057489      0t0      TCP ip-10-0-2-94.ec2.internal:46276->ec2-52-207-88-5.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   34u     IPv4 42056411      0t0      TCP ip-10-0-2-94.ec2.internal:44117->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   35u     IPv4 42057454      0t0      TCP ip-10-0-2-94.ec2.internal:46246->ec2-52-207-88-5.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   36u     IPv4 42056469      0t0      TCP ip-10-0-2-94.ec2.internal:44169->ec2-52-0-70-16.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   37u     IPv4 42056431      0t0      TCP ip-10-0-2-94.ec2.internal:44137->ec2-52-0-70-16.compute-1.amazonaws.com:https (CLOSE_WAIT)
    {service} 27085 {user}   38u     IPv4 42057523      0t0      TCP ip-10-0-2-94.ec2.internal:46306->ec2-52-207-88-5.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   39u     IPv4 42056511      0t0      TCP ip-10-0-2-94.ec2.internal:44201->ec2-52-0-70-16.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   40u     IPv4 42056539      0t0      TCP ip-10-0-2-94.ec2.internal:46338->ec2-52-207-88-5.compute-1.amazonaws.com:https (ESTABLISHED)
    

    Eventually (within 5-10 minutes) lsof stops reporting the state of the connection and merely states it's a TCP connection:

    COMMAND   PID   USER   FD      TYPE   DEVICE SIZE/OFF     NODE NAME
    {service} 27085 {user}   12u     sock      0,8      0t0 42056997 protocol: TCP
    {service} 27085 {user}   13u     sock      0,8      0t0 42057706 protocol: TCP
    {service} 27085 {user}   14u     sock      0,8      0t0 42056111 protocol: TCP
    {service} 27085 {user}   15u     sock      0,8      0t0 42057076 protocol: TCP
    {service} 27085 {user}   16u     sock      0,8      0t0 42057083 protocol: TCP
    {service} 27085 {user}   17u     sock      0,8      0t0 42056169 protocol: TCP
    {service} 27085 {user}   18u     sock      0,8      0t0 42057114 protocol: TCP
    {service} 27085 {user}   19u     sock      0,8      0t0 42057151 protocol: TCP
    {service} 27085 {user}   20u     IPv4 42057127      0t0      TCP ip-10-0-2-94.ec2.internal:20860->ec2-52-20-107-126.compute-1.amazonaws.com:https (ESTABLISHED)
    {service} 27085 {user}   21u     sock      0,8      0t0 42056184 protocol: TCP
    {service} 27085 {user}   22u     sock      0,8      0t0 42056206 protocol: TCP
    {service} 27085 {user}   23u     sock      0,8      0t0 42056216 protocol: TCP
    {service} 27085 {user}   24u     sock      0,8      0t0 42056233 protocol: TCP
    {service} 27085 {user}   25u     sock      0,8      0t0 42056248 protocol: TCP
    {service} 27085 {user}   26u     sock      0,8      0t0 42057212 protocol: TCP
    {service} 27085 {user}   27u     sock      0,8      0t0 42056339 protocol: TCP
    {service} 27085 {user}   28u     sock      0,8      0t0 42056281 protocol: TCP
    {service} 27085 {user}   29u     sock      0,8      0t0 42056288 protocol: TCP
    {service} 27085 {user}   30u     sock      0,8      0t0 42057383 protocol: TCP
    {service} 27085 {user}   31u     sock      0,8      0t0 42056381 protocol: TCP
    {service} 27085 {user}   32u     sock      0,8      0t0 42057433 protocol: TCP
    {service} 27085 {user}   33u     sock      0,8      0t0 42057489 protocol: TCP
    {service} 27085 {user}   34u     sock      0,8      0t0 42056411 protocol: TCP
    {service} 27085 {user}   35u     sock      0,8      0t0 42057454 protocol: TCP
    {service} 27085 {user}   36u     sock      0,8      0t0 42056469 protocol: TCP
    {service} 27085 {user}   37u     sock      0,8      0t0 42056431 protocol: TCP
    {service} 27085 {user}   38u     sock      0,8      0t0 42057523 protocol: TCP
    {service} 27085 {user}   39u     sock      0,8      0t0 42056511 protocol: TCP
    {service} 27085 {user}   40u     sock      0,8      0t0 42056539 protocol: TCP
    {service} 27085 {user}   41u     sock      0,8      0t0 42056547 protocol: TCP
    

    It appears rest.ably.io is resolving to the load balancer mentioned in the lsof output:

    dig rest.ably.io
    
    ; <<>> DiG 9.10.3-P4-Ubuntu <<>> rest.ably.io
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52768
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 1280
    ;; QUESTION SECTION:
    ;rest.ably.io.			IN	A
    
    ;; ANSWER SECTION:
    rest.ably.io.		17	IN	A	52.207.88.5
    rest.ably.io.		17	IN	A	52.0.70.16
    
    ;; Query time: 0 msec
    ;; SERVER: 127.0.0.1#53(127.0.0.1)
    ;; WHEN: Mon Sep 24 12:07:02 UTC 2018
    ;; MSG SIZE  rcvd: 73
    

    These leaking connections eventually overwhelm our service, causing our systems to fail. Looking at the client interface it appears there's no obligation on the consumer of the client lib to call a Close() method, so it seems like the client may be failing to do some cleanup internally?

    bug 
    opened by BRMatt 11
  • Go JSON / Binary / String support

    Go JSON / Binary / String support

    As discussed with @kouno, we need to be aware that ALL of our client libraries natively support three payload data types namely:

    • String UTF-8
    • Byte arrays (binary)
    • JSON

    Typically in dynamically typed languages, when you subscribe to messages, you will be delivered the data type automatically because when the message is received, it is decoded automatically, see https://github.com/ably/ably-ruby/blob/master/SPEC.md#ablymodelsmessageencoders.

    In more strongly typed languages such as Java, we still encode & decode automatically and return the correct data type, see https://github.com/ably/ably-java/blob/db50628fceb0af37c63c33693ab77dbb35d3c245/src/io/ably/types/BaseMessage.java#L97-L135.

    However, in Go, JSON is not a common data type and instead the norm is to Marshal JSON strings into typed Structs. The problem for us is that whilst we return a JSON data type in Ruby / Javascript / Java, for us to do this in Go we'd need to return a generic Interface{} object, see http://golang.org/src/encoding/json/decode.go?s=2340:2388#L57. We could do this, but my understanding is that this is largely frowned upon the Go community and instead JSON should be marshalled to a Struct. If we did return a generic interface, it's quite probable the developer would only then need to marshal it into another object so we're just adding unnecessary processing.

    I don't have a solution, but am raising this issue so that we can discuss.

    @paddybyers any thoughts?

    bug 
    opened by mattheworiordan 11
  • Update imports to reference vendored packages

    Update imports to reference vendored packages

    The dependencies have already been vendored using godep (see 5d8ca38) but they were not being referenced.

    This is the result of running godep save -r ./....

    enhancement 
    opened by lmars 10
  • Sometimes integration tests fail with a websocket dial error.

    Sometimes integration tests fail with a websocket dial error.

    One example of this was seen on this run https://github.com/ably/ably-go/runs/6405356210?check_suite_focus=true

    === RUN   TestRealtimePresence_Sync250
        realtime_presence_integration_test.go:71: 
            	Error Trace:	realtime_presence_integration_test.go:71
            	Error:      	Received unexpected error:
            	            	[ErrorInfo :websocket.Dial wss://sandbox-realtime.ably.io:443?echo=true&format=msgpack&heartbeats=true&key=_tmp_DELqOQ.4bzRew%3AZnRMoEAyCUwMR0BHKwYz3y7HUeuzkGl4FgEYMuHbmno&timestamp=1652358451326&v=1.2: read tcp 10.1.1.102:52358->52.85.35.170:443: read: connection reset by peer code=80003 disconnected statusCode=0] See https://help.ably.io/error/80003
            	Test:       	TestRealtimePresence_Sync250
    

    Note the error message "read: connection reset by peer". This feels like the sandbox server is closing the connection and the test then has an error because it has been disconnected.

    ┆Issue is synchronized with this Jira Task by Unito ┆sprint: SDK 2022-Q2-S5 26/05

    failing-test 
    opened by Rosalita 9
  • Ablytest

    Ablytest

    Hello 👋

    Thanks so much for the hard work in getting 1.2 released - I'm really excited to try it.

    To that end, we're trying to update from 1.1.5 to 1.2 but running into some difficulty. Some of the APIs have changed a good deal. But specifically preventing us right now is that ablytest has become internal: https://github.com/ably/ably-go/tree/v1.2.0/ably/internal/ablytest

    We've been using ablytest for integration tests for a long time (since this discussion from last year: https://github.com/ably/ably-go/issues/140). We're setting up a sandbox client and then publishing messages to it to make sure that all of our routing and message handling is working correctly. It has been very useful.

    We use two pieces of the ablytest package:

    ablytest.NewRestClient(nil) ablytest.Wait() (for publishing messages)

    Does the Ably team have a recommended replacement for the sandbox client? Or am I missing something?

    Thanks!

    ┆Sprint: Backlog

    opened by joshforbes 9
  • Testing challenges around use of embedded sync.Mutex in types

    Testing challenges around use of embedded sync.Mutex in types

    Some of the the types used in this project have sync.Mutex embedded directly into them e.g RealtimeChannel https://github.com/ably/ably-go/blob/main/ably/realtime_channel.go#L169 and RealtimePresence https://github.com/ably/ably-go/blob/main/ably/realtime_presence.go#L22

    the sync package states Values containing the types defined in this package should not be copied. This creates a challenge when we want to copy a mocked type that contains a sync.Mutex into a unit tests. We simply can't do this as go vet (correctly) objects to copying the mutex. We also have no way to test whether any particular sync.Mutex is locked or unlocked as a result of code execution because we can't use dependency injection to inject a mock mutex into the code.

    It might be worth investigating if representing sync.Mutex with the sync.Locker interface would make some of the code in this project testable at the unit test level. Interfaces are essentially mocking points and using sync.Locker could allow us to use a mock lock to make assertions in unit tests.

    ┆Issue is synchronized with this Jira Uncategorised by Unito ┆sprint: Backlog

    tests 
    opened by Rosalita 8
  • Consider updating documentation for changelog generation in release process section of CONTRIBUTING.md

    Consider updating documentation for changelog generation in release process section of CONTRIBUTING.md

    Our release process currently has a dependency on a developer having a working Ruby tool chain in order to generate release notes. There’s been a few times where SDK developers have had issues with their ruby toolchains which has ended up being a blocker for releasing.

    Since this release process was written, Github have added a changelog generator to their UI. We should consider moving to this rather than depending on the ruby gem github_changelog_generator

    Acceptance criteria:

    • Update CONTRIBUTING.md to explain the process required to generate a changelog using the GitHub UI
    • Rather than pushing the tag to GitHub, the option to tell GitHub to create a new tag on release should be used.

    ┆Issue is synchronized with this Jira Uncategorised by Unito ┆sprint: Backlog

    opened by Rosalita 2
  • Implement incremental backoff and jitter

    Implement incremental backoff and jitter

    Please see the example implementation in js here https://github.com/ably/ably-js/issues/997

    Incremental backoff and jitter was added to the features spec in https://github.com/ably/docs/pull/1445

    To implement this we need to change the retry behaviour for:

    • When the client connection is in the DISCONNECTED state
    • When a RealtimeChannel is in the SUSPENDED state

    The new retry behaviour is specified in RTB1 of the features spec.

    RTB1a

    The backoff coefficient described in RTB1a can be calculated in javascript like so:

    function getBackoffCoefficient(n) {
      return Math.min((n + 2) / 3, 2);
    }
    

    RTB1b

    The jitter coefficient described in RTB1b can be calculated in javascript like so:

    function getJitterCoefficient() {
      return 1 - Math.random() * 0.2;
    }
    

    RTB1

    The overall retry time calculation should look like:

    function getRetryTime(initValue, n) {
      return initValue * getBackoffCoefficient(n) * getJitterCoefficient();
    }
    

    The following code can be used to test it:

    [1, 2, 3, 4, 5].forEach((n) => {
      console.log(getRetryTime(initValue, n));
    });
    

    Which, with an initValue of 15 (seconds) should print something like:

    13.917470451245713
    18.415226855678757
    20.444851032898747
    26.650729887092275
    27.803382948778786
    
    enhancement 
    opened by deanna-lad 0
  • Implement token revocation

    Implement token revocation

    Please implement the token revocation as specified in the spec documentation as created ably/docs#1426 and using this prototype as a referencehttps://github.com/ably/ably-cocoa/pull/1430 and issue in cocoa https://github.com/ably/ably-cocoa/issues/1429

    To dos:

    • Create a new branch that will contain token revocation work
    • Add necessary classes / functions following spec and reference implementation. Ikbal is happy to answer any questions.
    • For networking layer (Make REST request, encode, decode), follow the existing pattern on your repo . Make sure to check REST API documentation
    • Write tests for the feature

    ┆Issue is synchronized with this Jira Uncategorised by Unito ┆sprint: Backlog

    enhancement 
    opened by deanna-lad 0
  • Sometimes Panic happens during tests for TestRealtimeChannel_RTL6c2_PublishEnqueue

    Sometimes Panic happens during tests for TestRealtimeChannel_RTL6c2_PublishEnqueue

    The test TestRealtimeChannel_RTL6c2_PublishEnqueue contains a number of sub-tests which test for different connection and channel states. Sometimes this test fails with the message panic: Ack called but queue is empty. however the failure does not always occur for the same sub-test.

    For example in this run the panic happened while the 9th sub-test was running for integration-test (1.17, json) https://github.com/ably/ably-go/runs/6514937687?check_suite_focus=true

    ci log

    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_INITIALIZED,_channel_is_INITIALIZED
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_CONNECTING,_channel_is_INITIALIZED
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_CONNECTING,_channel_is_ATTACHING
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_DISCONNECTED,_channel_is_INITIALIZED
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_DISCONNECTED,_channel_is_ATTACHING
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_DISCONNECTED,_channel_is_ATTACHED
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_DISCONNECTED,_channel_is_DETACHING
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_DISCONNECTED,_channel_is_DETACHED
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_CONNECTING,_channel_is_ATTACHED
    panic: Ack called but queue is empty.
    
    goroutine 2516 [running]:
    github.com/ably/ably-go/ably.(*pendingEmitter).Ack(0xc00019a598, 0xc00020ad20, 0x0)
    	/home/runner/work/ably-go/ably-go/ably/state.go:154 +0x7d9
    github.com/ably/ably-go/ably.(*Connection).eventloop(0xc00019a500)
    	/home/runner/work/ably-go/ably-go/ably/realtime_conn.go:724 +0x928
    created by github.com/ably/ably-go/ably.(*Connection).connectWith
    

    Link to test observability server for this run: https://test-observability.herokuapp.com/repos/ably/ably-go/uploads/8edbf9c8-93f6-4610-9bb4-fea75d5c484e

    On another occasion, the panic happened while the 7th sub-test was running. This was the test run for integration-test (1.18, msgpack https://github.com/ably/ably-go/runs/6692532981?check_suite_focus=true

    ci log

    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_INITIALIZED,_channel_is_INITIALIZED
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_CONNECTING,_channel_is_INITIALIZED
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_CONNECTING,_channel_is_ATTACHING
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_DISCONNECTED,_channel_is_INITIALIZED
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_DISCONNECTED,_channel_is_ATTACHING
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_DISCONNECTED,_channel_is_ATTACHED
    === RUN   TestRealtimeChannel_RTL6c2_PublishEnqueue/when_connection_is_DISCONNECTED,_channel_is_DETACHING
    panic: Ack called but queue is empty.
    
    goroutine 2384 [running]:
    github.com/ably/ably-go/ably.(*pendingEmitter).Ack(0xc00084ee58, 0xc00021f260, 0x0)
    	/home/runner/work/ably-go/ably-go/ably/state.go:154 +0x811
    github.com/ably/ably-go/ably.(*Connection).eventloop(0xc00084edc0)
    	/home/runner/work/ably-go/ably-go/ably/realtime_conn.go:724 +0x916
    created by github.com/ably/ably-go/ably.(*Connection).connectWith
    	/home/runner/work/ably-go/ably-go/ably/realtime_conn.go:384 +0x61a
    

    This issue has been seen for both Go version 1.17 and 1.18 and both json and msgpack protocols. It has also been seen on a CI run for a branch which only contained a whitespace change.

    Investigation is needed to get to the bottom of this panic.

    ┆Issue is synchronized with this Jira Uncategorised by Unito ┆sprint: Backlog

    failing-test 
    opened by Rosalita 0
  • Unstable integration test TestAuth_ClientID/Auth_ClientID

    Unstable integration test TestAuth_ClientID/Auth_ClientID

    Link to test run where this test failed for integration-test (1.17, json)

    https://github.com/ably/ably-go/runs/6690535221?check_suite_focus=true

    Link to test observability server for this run

    https://test-observability.herokuapp.com/repos/ably/ably-go/uploads/edabc612-128e-44f8-aed6-73a351d622a7

    CI log

    === RUN   TestAuth_ClientID/Auth_ClientID
        auth_integration_test.go:529: 
            	Error Trace:	auth_integration_test.go:5[29](https://github.com/ably/ably-go/runs/6690535221?check_suite_focus=true#step:6:30)
            	Error:      	Not equal: 
            	            	expected: ably.ConnectionState{name:"FAILED"}
            	            	actual  : ably.ConnectionState{name:"CONNECTED"}
            	            	
            	            	Diff:
            	            	--- Expected
            	            	+++ Actual
            	            	@@ -1,3 +1,3 @@
            	            	 (ably.ConnectionState) {
            	            	- name: (string) (len=6) "FAILED"
            	            	+ name: (string) (len=9) "CONNECTED"
            	            	 }
            	Test:       	TestAuth_ClientID/Auth_ClientID
            	Messages:   	want state="FAILED"; got "CONNECTED"
    

    This failure was seen on a CI run for a branch which only contained a whitespace change. This indicates we might have a problem with this test being unstable and we should investigate further.

    ┆Issue is synchronized with this Jira Uncategorised by Unito ┆sprint: Backlog

    failing-test 
    opened by Rosalita 0
  • Experiment to start adding fuzzing tests to the project.

    Experiment to start adding fuzzing tests to the project.

    A new way of testing called fuzzing was added in Go 1.18 (see tutorial https://go.dev/doc/tutorial/fuzz)

    Both myself and @lmars think adding fuzz tests to the project is a good idea.

    A good starting point for fuzzing would be to consider user defined strings. One place that a user can define a string is the name they provide when they create a channel.

    I would propose as an experiment, we add a single fuzz test for channel.Get() so that we can learn more about this testing technique, assess if fuzz tests are suitable for this project and (if they are) create a foundation upon which more fuzzing tests can be added. Note that fuzz tests are long running tests which are started and left running for a duration of time (similar to soak tests), so it will not be practical to run them in the CI pipeline.

    Acceptance criteria:

    1. Implement a new fuzzing test for channel.Get()
    2. Run the new fuzz test and raise any new bugs which are discovered by the test.
    3. Update the tests section of CONTRIBUTING.md to explain how the fuzz test can be run locally.

    ┆Issue is synchronized with this Jira Uncategorised by Unito ┆sprint: Backlog

    tests 
    opened by Rosalita 0
Releases(v1.2.8)
  • v1.2.8(Jul 1, 2022)

  • v1.2.7(Jun 9, 2022)

    1.2.7 (2022-06-09)

    Full Changelog

    Implemented enhancements:

    • Add support to get channel lifecycle status #509

    Fixed bugs:

    • Missing pointer safety when creating a new Realtime Client #537
    • realtime: missing test for sync resume (disconnection while sync is in progress) #34

    Closed issues:

    • Remove dependency on test.sh bash script to run the tests #530
    • Unstable test TestStats_Direction_RSC6b2 #520
    • Remove flaky unit tests TestAfterOK and TestAfterCanceled in package ablyutil #514
    • Tests for packages ablyutil and ablytest are running more than once in the CI pipeline #504
    • Flaky POST /apps: "Unable to modify existing channel namespace" #354
    • Document ably/generate.go #351
    • Document the project structure in our contributing guide #350
    • Lint code, probably using gofmt #346
    • Conform ReadMe and create Contributing Document #340

    Merged pull requests:

    • fix nil pointer issue #543 (mohyour)
    • Use pointers to mock types which contain embedded sync.mutex #542 (Rosalita)
    • Increased unit test coverage #534 (Rosalita)
    • Chore/update readme #533 (mohyour)
    • Remove dependency on test.sh bash script to run the tests #531 (Rosalita)
    • revert git commit 787e6e98e5dfc2bf848e2cfdbe64bcff901ded2a #528 (Rosalita)
    • Fix small capitalisation error in function name #527 (Rosalita)
    • Fix flakey test by using a subtest to separate test set-up from test execution #525 (Rosalita)
    • Fixes test failure in scenario where test is retried as app already exists with namespace. #524 (Rosalita)
    • log request time outs when attempting retry #523 (Rosalita)
    • #509 add support to get lifecycle status #521 (mohyour)
    • Remove unstable time based unit tests from package ablyutil #518 (Rosalita)
    • Add code formatting check to CI pipeline and format all files #517 (Rosalita)
    • update dependency stretchr/testify from 1.4.0 to 1.7.1 #516 (Rosalita)
    • Split integration tests into separate workflow #515 (owenpearson)
    • Increased internal unit test coverage for error.go #510 (Rosalita)
    • #342 - update codec dependency #506 (mohyour)
    • Tests/add tags #505 (Rosalita)
    Source code(tar.gz)
    Source code(zip)
  • v1.2.6(May 11, 2022)

    Change Log

    1.2.6 (2022-5-10)

    Full Changelog

    Fixed bugs:

    • AblyREST.Request() does not work #486
    • Callback not invoked, despite message being received from server #434
    • Undescriptive errors; possible broken fallback functionality #125
    • HTTPPaginatedResult and PaginatedResult are missing some methods #120
    • ID and Client ID is blank on realtime incoming messages. #58
    • Do not persist authorise attributes force & timestamp #54

    Closed issues:

    • go Update urls in readme #491
    • Research a new API Design that allows Ably to be mocked in unit tests. #488
    • Once test observability is in place try to turn all tests back on. #479
    • Support Go 1.18 #474
    • Test improvements - Standardise test assertions #456
    • Investigate re-enabling flaky tests. #438
    • Skipped Test: TestPresenceGet_RSP3_RSP3a1 #415
    • Skipped Test: TestPresenceHistory_RSP4_RSP4b3 #414
    • Skipped Test: TestHistory_Direction_RSL2b2 #413
    • Skipped Test: TestRealtimePresence_EnsureChannelIsAttached #412
    • Skipped Test: TestRealtimePresence_Sync250 #411
    • Skipped Test: TestRealtimeConn_BreakConnLoopOnInactiveState #410
    • Skipped Test: TestRealtimeConn_RTN19b #407
    • Skipped Test: TestRealtimeConn_RTN23 #405
    • Skipped Test: TestRealtimeConn_RTN15d_MessageRecovery #404
    • Skipped Test: TestRealtimeConn_RTN12_Connection_Close RTN12d #403
    • Skipped Test: TestRealtime_DontCrashOnCloseWhenEchoOff #400
    • Skipped Test: TestRealtimeChannel_RTL4_Attach RTL4j2 #398
    • Skipped Test: TestAuth_RSA7c #393
    • Document ably/export_test.go #352
    • Rename ClientOption type to something better describing its purpose #348
    • Clean up ably/doc_test.go Example_paginatedResults() #345
    • Update golang.org/x/net dependency (January 2019 > June 2021) #341
    • Flaky test in 1.2 branch: TestRealtimePresence_Sync250 #338
    • Flaky test in 1.2 branch: TestRealtimeConn_RTN19b #333
    • ably-go: add logging to rest & realtime clients #38

    Merged pull requests:

    Source code(tar.gz)
    Source code(zip)
  • v1.2.5(Mar 14, 2022)

    1.2.5 (2022-03-09)

    Full Changelog

    Fixed bugs:

    • Failure to get channel with slash #463
    • Hang when joining presence #462
    • Frequently, a client can not get their own presence from a channel after making one call to channel.Presence.Enter. #436

    Closed issues:

    • Test improvements - Move integration tests to their own package. #458
    • SPIKE : Find a way to run a single integration test with a CLI command #449
    • Test improvements - Separate unit tests and integration tests. #447
    • Release ably-go #440

    Merged pull requests:

    Source code(tar.gz)
    Source code(zip)
  • v1.2.4(Feb 10, 2022)

    1.2.4 (2022-02-10)

    Full Changelog

    Fixed bugs:

    • Subscribe(), Attach() are either counterintuitive or broken #155

    Closed issues:

    • Running tests locally, one test always fails. #445
    • Add ConnectionKey to message #442
    • Follow the lead of the Go team and support the last two major versions of Go #431
    • Remove go.mod from examples #428
    • Refine the documented release procedure #427
    • Assess suitability of go 1.13 in our go.mod #344

    Merged pull requests:

    • Deprecate RESTChannel.PublishMultipleWithOptions #450 (lmars)
    • Fix unit test that always failed when run locally. #446 (Rosalita)
    • Add connection key to messages. #443 (Rosalita)
    • Disable flaky tests. #439 (Rosalita)
    • Add ConnectionKey to message #437 (ken8203)
    • Documentation improvements for RealtimePresence. #435 (Rosalita)
    • examples: Remove go.mod and go.sum #430 (lmars)
    • Update Go version to 1.16 in go.mod, drop < 1.16 from versions tested, update README.md fixes #431 #426 (Rosalita)
    Source code(tar.gz)
    Source code(zip)
  • v1.2.3(Oct 27, 2021)

    Sorry for the noise but we made a mistake when we released version 1.2.2 of this library. :facepalm:

    The v1.2.2 tag was pushed against the wrong commit, meaning that the library was announcing itself as at version 1.2.1 to the Ably service. This release (assuming we get the tag push right this time :stuck_out_tongue_winking_eye:) will correctly identify itself as version 1.2.3.

    Source code(tar.gz)
    Source code(zip)
  • v1.2.2(Oct 22, 2021)

    Full Changelog

    Implemented enhancements:

    • Implement RSC7d (Ably-Agent header) #302

    Closed issues:

    • Ablytest #358
    • RTN6: CONNECTED when connection is established #232
    • RSA1, RSA2, RSA11: Basic auth #216

    Merged pull requests:

    Source code(tar.gz)
    Source code(zip)
  • v1.2.1(Aug 9, 2021)

    Full Changelog

    Implemented enhancements:

    • Need a migration guide for users going from 1.1.5 to 1.2.0 #361
    • Changelog and release tag #48

    Merged pull requests:

    • Update generated files #371 (lmars)
    • Don't set message encoding for valid utf-8 string data #370 (lmars)
    • Export the ablytest package #366 (tcard)
    • Migration guide 1.1.5 to 1.2.0 #364 (QuintinWillison)
    • Update README.md #362 (AndyNicks)
    • RTC8a: client-requested reauthorization while CONNECTED (to main branch) #357 (tcard)
    • RTC8a: client-requested reauthorization while CONNECTED #336 (tcard)
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Jul 9, 2021)

    Version 1.2.0 is out of pre-release!

    Full Changelog since v1.1.5

    Full Changelog since v1.2.0-apipreview.6

    Implemented enhancements:

    • Add enough logs to troubleshoot problems #160

    Closed issues:

    • Create code snippets for homepage (go) #324
    • Unexport package proto, ablycrypto, ablytest #291
    • API compliance - Go 1.2 #271
    • RTN7: ACK and NACK #215

    Merged pull requests:

    v1.2.0-apipreview.6 (2021-06-17)

    Full Changelog

    Fixed bugs:

    • IV shouldn't be reused between messages #330

    Closed issues:

    • RTN21: Overriding connectionDetails #227

    Merged pull requests:

    v1.2.0-apipreview.5 (2021-06-04)

    Full Changelog

    Implemented enhancements:

    • Common design for PaginatedResult-related methods #278
    • Add Connection Error Handling - 0.8 feature #51

    Fixed bugs:

    • API completeness #50
    • Passing tests appear to have failed in Travis #47
    • Go JSON / Binary / String support #9

    Closed issues:

    • Fix RTN14c test to include full connection establishment #315
    • Flaky test in 1.2 branch: TestStatsPagination_RSC6a_RSCb3 #313
    • Flaky test in 1.2 branch: TestPresenceHistory_Direction_RSP4b2 #310
    • Flaky test in 1.2 branch: TestRealtimeChannel_Detach #309
    • Fix channel iteration methods #307
    • RTN12: Connection.close #262
    • RTL2f: ChannelEvent RESUMED flag #243
    • RTL17: Only dispatch messages when ATTACHED #240
    • RTL14: ERROR message for channel #238
    • RTL12: Random incoming ATTACHED message #237
    • RTN3: Connection.autoConnect #229
    • RTN2: WebSocket query params #226
    • RTN10: Connection.serial #224
    • RTN24: Handle random CONNECTED message #223
    • RTL5: Channel.detach #212
    • RTL4: Channel.attach #211
    • Bring back reverted README examples #207

    Merged pull requests:

    • Unexport CipherParams.IV, useful only for tests #334 (tcard)
    • Unexport package proto, ablycrypto, ablytest #332 (tcard)
    • Fix/conflict integration 1.2 #329 (sacOO7)
    • [FIX CONFLICTS] Merge env. fallbacks to 1.2 #328 (sacOO7)
    • Replace all ts \*testing.T instances with t #326 (tcard)
    • Simplify and uniformize logging #321 (tcard)
    • Websocket query params #320 (sacOO7)
    • Use persisted namespace for history tests #319 (tcard)
    • Avoid current stats period interference with fixtures in tests #318 (tcard)
    • Rewrite RTN14c to test full connection establishment #317 (tcard)
    • Allow setting connection and request timeouts separately #312 (Jmgr)
    • Remove flaky TestRealtimeChannel_Detach #311 (tcard)
    • Fix channel iteration #308 (sacOO7)
    • Connection Autoconnect #306 (sacOO7)
    • Connection serial #305 (sacOO7)
    • Override connectionDetails #304 (sacOO7)
    • Rename PublishBatch -> PublishMultiple #303 (tcard)
    • Migrate Presence.get and REST.request to new paginated results #301 (tcard)
    • Remove Ping public Interface #300 (sacOO7)
    • Channel Attach #299 (sacOO7)
    • Channel Detach #298 (sacOO7)
    • Connection Close #297 (sacOO7)
    • Conform license and copyright #296 (QuintinWillison)
    • RTN24, Handle Random Connected Message #295 (sacOO7)
    • Channel message dispatch only when it's attached #294 (sacOO7)
    • Adapt History to follow new paginated result design #292 (tcard)
    • FailedChannelState on error message #289 (sacOO7)
    • Channel resume #288 (sacOO7)
    • Ensure generated code is up-to-date in CI #287 (tcard)
    • Added H2 with Resources #285 (ramiro-nd)
    • Amend workflow branch name #284 (owenpearson)
    • Ably 1.2 examples #283 (sacOO7)
    • Adapt Stats to follow new paginated result design #281 (tcard)
    • Add scripts/test.sh for running tests #279 (lmars)
    • TestFixConnLeak_ISSUE89: Change the way it detects closed conns #277 (tcard)
    • Generate env fallbacks #268 (sacOO7)

    v1.2.0-apipreview.4 (2021-02-11)

    Full Changelog

    Implemented enhancements:

    • Add missing context.Context arguments #275
    • Defaults: Generate environment fallbacks #198
    • Implement support for connection recovery and resume #52

    Closed issues:

    • 'Account disabled' error gets sent as DISCONNECTED #269
    • ttl seems to be set to null in a created token request? #266
    • v1.2 API design #197

    Merged pull requests:

    v1.2.0-apipreview.3 (2020-11-17)

    Full Changelog

    Implemented enhancements:

    • RTL9: Channel presence #264

    Closed issues:

    • Missing lib=go-<version> querystring param in connections #209

    Merged pull requests:

    v1.2.0-apipreview.2 (2020-11-09)

    Full Changelog

    Merged pull requests:

    • RTL6c: Publish while not connected #208 (tcard)
    • Update README for 1.2 preview, with associated fixes #206 (tcard)
    • add rtn14 - Connection opening failures: #172 (gernest)

    v1.2.0-apipreview.1 (2020-10-21)

    Full Changelog

    Merged pull requests:

    • Implement options as package-level functions #205 (tcard)
    • v1.2-compliant message and presence publish and subscribe #202 (tcard)

    v1.2.0-apipreview.0 (2020-10-16)

    Full Changelog

    Fixed bugs:

    • Rest.request call timing out doesn't result in the errorMessage being set in the httpPaginatedResponse? #192
    • Channel attach fails in the DISCONNECTED state #189
    • TestFixConnLeak_ISSUE89 is flaky #132

    Closed issues:

    • Reauthentication with Presence #164

    Merged pull requests:

    • Remove things from public API that aren't in the spec #201 (tcard)
    • Explicitly annotate enum vars so that godoc places them with the type #200 (tcard)
    • Introduce ErrorCode type for predefined error codes #199 (tcard)
    • Merge main into 1.2 #196 (tcard)
    • Always include serial values in encoded protocol messages #195 (lmars)
    • Handle non-PaginatedResult but otherwise valid HTTP error responses #194 (tcard)
    • Add HTTPRequestTimeout option with 10s default #193 (tcard)
    • Ad-hoc fix for enqueuing attach attempt when DISCONNECTED. #191 (tcard)
    • RTL2: EventEmitter for channel events; remove old State #190 (tcard)
    • RTN15e: Check that Connection.Key changes on reconnections. #188 (tcard)
    • RTN15d: Add a test for message delivery on connection recovery. #187 (tcard)
    • RTL13: Handle DETACHED while not DETACHING. #185 (tcard)
    • Fix test for Heartbeat #183 (gernest)
    • Fix race condition in RTN15i test #182 (tcard)
    • RTN15g: Don't attempt resume after server has discarded state #181 (tcard)
    • RTN15i: Add test for already existing functionality. #180 (tcard)
    • RTN15h*: Handle incoming DISCONNECTED while CONNECTED #179 (tcard)
    • Temporarily skip test for RTN23. #178 (tcard)
    • Fix data race in RTN23 test. #177 (tcard)
    • Have a single Travis build as originally intended. #176 (tcard)
    • proto: Decode ms durations as a time.Duration wrapper. #174 (tcard)
    • Fix instances of old nil *ChannelOptions becoming nil option func. #173 (tcard)
    • remove unused fields from Connection #171 (gernest)
    • Add RTN23- heartbeats #169 (gernest)
    • Rename master to main #167 (QuintinWillison)
    • Add rtn16 #165 (gernest)
    • v1.2 ChannelOptions #146 (tcard)
    • v1.2 ClientOptions #145 (tcard)
    • v1.2 event emitter for connection (RTN4) #144 (tcard)
    Source code(tar.gz)
    Source code(zip)
  • v1.1.5(May 27, 2020)

  • v1.1.4(Apr 27, 2020)

    Full Changelog

    Fixed bugs:

    • Lib failing to retrying on 5xx if it can't parse the body #154
    • Flaky TestAuth_ClientID test #80
    • Likely leaking goroutines in multiple places #68

    Closed issues:

    • Implementing reauthentication before or after token expires #153

    Merged pull requests:

    • Properly set Error.StatusCode #157 (gernest)
    • Use ClientOptions.TLSPort for tls connections #156 (gernest)
    • RTN15a: Reconnect after networking error. #152 (tcard)
    • Fix goroutine leaks #151 (tcard)
    • Remove fmt.Println leftovers. #150 (tcard)
    • Don't read from connection on inactive state. #149 (tcard)
    • RTN23a: Receive from WebSocket with a timeout. #148 (tcard)
    Source code(tar.gz)
    Source code(zip)
  • v1.1.3(Apr 2, 2020)

  • v1.1.2(Jan 20, 2020)

  • v1.1.1(Feb 6, 2019)

  • v0.8.2(Nov 1, 2018)

  • v0.8.1(Oct 12, 2018)

  • v0.8.0-beta.1(Sep 6, 2018)

  • v0.8.0-beta.0(Oct 13, 2017)

    This is a work-in-progress release moving towards a v0.8 stable release.

    Known limitations at this time:

    • Realtime connection recovery is not implemented
    • Realtime connection failure handling is not implemented
    • ChannelsOptions and CipherParams are not supported when creating a Channel
    • Realtime Ping function is not implemented
    • Fallback support not implemented
    • API compatibility is not guaranteed
    Source code(tar.gz)
    Source code(zip)
Owner
Ably Realtime - our client library SDKs and libraries
Ably is a serverless infrastructure provider for the realtime Internet. We solve the complex problems to do with maintaining a global data stream network.
Ably Realtime - our client library SDKs and libraries
Simple-messaging - Brokerless messaging. Pub/Sub. Producer/Consumer. Pure Go. No C.

Simple Messaging Simple messaging for pub/sub and producer/consumer. Pure Go! Usage Request-Response Producer: consumerAddr, err := net.ResolveTCPAddr

IchHabeKeineNamen 1 Jan 20, 2022
socket.io library for golang, a realtime application framework.

go-socket.io go-socket.io is library an implementation of Socket.IO in Golang, which is a realtime application framework. Current this library support

Googol Lee 4.7k Jul 1, 2022
Go-notification - Realtime notification system with golang

Realtime notification system Used Apache kafka gRPC & PROTOBUF MongoDB restapi w

vishalvishnu 2 Feb 16, 2022
Golang client for NATS, the cloud native messaging system.

NATS - Go Client A Go client for the NATS messaging system. Installation # Go client go get github.com/nats-io/nats.go/ # Server go get github.com/na

NATS - The Cloud Native Messaging System 4k Jun 29, 2022
A dead simple Go library for sending notifications to various messaging services.

A dead simple Go library for sending notifications to various messaging services. About Notify arose from my own need for one of my api server running

Niko Köser 1.2k Jun 28, 2022
💨 A real time messaging system to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.

Beaver A Real Time Messaging Server. Beaver is a real-time messaging server. With beaver you can easily build scalable in-app notifications, realtime

Ahmed 1.3k Jun 27, 2022
Scalable real-time messaging server in language-agnostic way

Centrifugo is a scalable real-time messaging server in language-agnostic way. Centrifugo works in conjunction with application backend written in any

Centrifugal 6.1k Jun 28, 2022
websocket based messaging server written in golang

Guble Messaging Server Guble is a simple user-facing messaging and data replication server written in Go. Overview Guble is in an early state (release

Sebastian Mancke 151 Jan 23, 2022
Abstraction layer for simple rabbitMQ connection, messaging and administration

Jazz Abstraction layer for quick and simple rabbitMQ connection, messaging and administration. Inspired by Jazz Jackrabbit and his eternal hatred towa

SOCIFI Ltd. 15 May 21, 2022
High-Performance server for NATS, the cloud native messaging system.

NATS is a simple, secure and performant communications system for digital systems, services and devices. NATS is part of the Cloud Native Computing Fo

NATS - The Cloud Native Messaging System 11.1k Jun 28, 2022
A quick introduction to how Apache Kafka works and differs from other messaging systems using an example application.

Apache Kafka in 6 minutes A quick introduction to how Apache Kafka works and differs from other messaging systems using an example application. In thi

bagher sohrabi 2 Oct 27, 2021
Golang Restful API Messaging using GORM ORM (MySQL) Gorilla Mux

Golang Restful API Messaging using GORM ORM (MySQL) Gorilla Mux Getting Started Folder Structure This is my folder structure under my $GOPATH or $HOME

Septian Ramadhan 0 Dec 14, 2021
Neutrino Corporation 2 Apr 12, 2022
Go-threema - Threema messaging from Go

Threema messaging from Go This is a Threema bot library written in Go. It uses p

Péter Szilágyi 14 May 30, 2022
golang client library to Viessmann Vitotrol web service

Package go-vitotrol provides access to the Viessmann™ Vitotrol™ cloud API for controlling/monitoring boilers. See https://www.viessmann.com/app_vitoda

Maxime Soulé 18 Jun 23, 2022
RES Service protocol library for Go

RES Service for Go Synchronize Your Clients Go package used to create REST, real time, and RPC APIs, where all your reactive web clients are synchroni

Samuel Jirénius 58 May 28, 2022
Cluster extensions for Sarama, the Go client library for Apache Kafka 0.9

Cluster extensions for Sarama, the Go client library for Apache Kafka 0.9 (and later).

Black Square Media 1k Jun 15, 2022
Apache Pulsar Go Client Library

Apache Pulsar Go Client Library A Go client library for the Apache Pulsar project. Goal This projects is developing a pure-Go client library for Pulsa

The Apache Software Foundation 457 Jun 22, 2022
It's client library written in Golang for interacting with Linkedin Cruise Control using its HTTP API.

go-cruise-control It's client library (written in Golang) for interacting with Linkedin Cruise Control using its HTTP API. Supported Cruise Control ve

Banzai Cloud 1 Jan 10, 2022