Skip to content

Commit

Permalink
Merge pull request #985 from ably/rest-lifecycle-status
Browse files Browse the repository at this point in the history
Rest lifecycle status RSL8
  • Loading branch information
owenpearson authored May 27, 2022
2 parents 0e0710f + 654699b commit 18132ad
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 14 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ ably-js.iml
node_modules
npm-debug.log
.tool-versions
/browser/static
build/
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,16 @@ channel.presence.history(function(err, messagesPage) { // PaginatedResult
channel.history({start: ..., end: ..., limit: ..., direction: ...}, function(err, messagesPage) { ...});
```

### Getting the status of a channel

```javascript
channel.status(function(err, channelDetails) {
channelDetails.channelId // The name of the channel
channelDetails.status.isActive // A boolean indicating whether the channel is active
channelDetails.status.occupancy // Contains metadata relating to the occupants of the channel
});
```

### Generate Token and Token Request

See https://www.ably.com/docs/general/authentication for an
Expand Down Expand Up @@ -518,6 +528,10 @@ const ablyRestPromiseExample = async () => {
const history = await channel.history({ limit: 25 });
console.log(await history.current());

// Getting the status of a channel
const channelDetails = await channel.status();
console.log(channelDetails);

// Requesting a token
const token = await client.auth.requestToken(tokenParams);

Expand All @@ -531,7 +545,7 @@ const ablyRestPromiseExample = async () => {
// Fetching the Ably service time
const time = await client.time();
console.log(`Ably service time: ${time}`);

client.close();
};

Expand Down
25 changes: 25 additions & 0 deletions ably.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,29 @@ declare namespace Types {

type Transport = 'web_socket' | 'xhr_streaming' | 'xhr_polling' | 'jsonp' | 'comet';

interface ChannelDetails {
channelId: string;
status: ChannelStatus;
}

interface ChannelStatus {
isActive: boolean;
occupancy: ChannelOccupancy;
}

interface ChannelOccupancy {
metrics: ChannelMetrics;
}

interface ChannelMetrics {
connections: number;
presenceConnections: number;
presenceMembers: number;
presenceSubscribers: number;
publishers: number;
subscribers: number;
}

// Interfaces
interface ClientOptions extends AuthOptions {
/**
Expand Down Expand Up @@ -650,13 +673,15 @@ declare namespace Types {
publish(messages: any, callback?: errorCallback): void;
publish(name: string, messages: any, callback?: errorCallback): void;
publish(name: string, messages: any, options?: PublishOptions, callback?: errorCallback): void;
status(callback: StandardCallback<ChannelDetails>): void;
}

class ChannelPromise extends ChannelBase {
presence: PresencePromise;
history: (params?: RestHistoryParams) => Promise<PaginatedResult<Message>>;
publish(messages: any, options?: PublishOptions): Promise<void>;
publish(name: string, messages: any, options?: PublishOptions): Promise<void>;
status(): Promise<ChannelDetails>;
}

class RealtimeChannelBase extends EventEmitter<channelEventCallback, ChannelStateChange, ChannelEvent> {
Expand Down
14 changes: 13 additions & 1 deletion src/common/lib/client/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import ErrorInfo from '../types/errorinfo';
import PaginatedResource, { PaginatedResult } from './paginatedresource';
import Resource, { ResourceCallback } from './resource';
import { ChannelOptions } from '../../types/channel';
import { PaginatedResultCallback } from '../../types/utils';
import { PaginatedResultCallback, StandardCallback } from '../../types/utils';
import Rest from './rest';
import Realtime from './realtime';
import * as API from '../../../../ably';
import Platform from 'common/platform';

interface RestHistoryParams {
Expand Down Expand Up @@ -189,6 +190,17 @@ class Channel extends EventEmitter {
_publish(requestBody: unknown, headers: Record<string, string>, params: any, callback: ResourceCallback): void {
Resource.post(this.rest, this.basePath + '/messages', requestBody, headers, params, null, callback);
}

status(callback?: StandardCallback<API.Types.ChannelDetails>): void | Promise<API.Types.ChannelDetails> {
if (typeof callback !== 'function' && this.rest.options.promises) {
return Utils.promisify(this, 'status', []);
}

const format = this.rest.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json;
const headers = Utils.defaultPostHeaders(format);

Resource.get<API.Types.ChannelDetails>(this.rest, this.basePath, headers, {}, format, callback || noop);
}
}

export default Channel;
20 changes: 10 additions & 10 deletions src/common/lib/client/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function withAuthDetails(
}
}

function unenvelope(callback: ResourceCallback, format: Utils.Format | null): ResourceCallback {
function unenvelope<T>(callback: ResourceCallback<T>, format: Utils.Format | null): ResourceCallback<T> {
return (err, body, outerHeaders, unpacked, outerStatusCode) => {
if (err && !body) {
callback(err);
Expand Down Expand Up @@ -85,8 +85,8 @@ function urlFromPathAndParams(path: string, params: Record<string, any>) {
return path + (params ? '?' : '') + paramString(params);
}

function logResponseHandler(
callback: ResourceCallback,
function logResponseHandler<T>(
callback: ResourceCallback<T>,
method: HttpMethods,
path: string,
params: Record<string, string>
Expand All @@ -113,27 +113,27 @@ function logResponseHandler(
);
}
if (callback) {
callback(err, body, headers, unpacked, statusCode);
callback(err, body as T, headers, unpacked, statusCode);
}
};
}

export type ResourceCallback = (
export type ResourceCallback<T = unknown> = (
err: ErrorInfo | null,
body?: unknown,
body?: T,
headers?: Record<string, string>,
unpacked?: boolean,
statusCode?: number
) => void;

class Resource {
static get(
static get<T = unknown>(
rest: Rest,
path: string,
headers: Record<string, string>,
params: Record<string, any>,
envelope: Utils.Format | null,
callback: ResourceCallback
callback: ResourceCallback<T>
): void {
Resource.do(HttpMethods.Get, rest, path, null, headers, params, envelope, callback);
}
Expand Down Expand Up @@ -185,15 +185,15 @@ class Resource {
Resource.do(HttpMethods.Put, rest, path, body, headers, params, envelope, callback);
}

static do(
static do<T>(
method: HttpMethods,
rest: Rest,
path: string,
body: unknown,
headers: Record<string, string>,
params: Record<string, any>,
envelope: Utils.Format | null,
callback: ResourceCallback
callback: ResourceCallback<T>
): void {
if (Logger.shouldLog(Logger.LOG_MICRO)) {
callback = logResponseHandler(callback, method, path, params);
Expand Down
71 changes: 71 additions & 0 deletions test/rest/status.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
'use strict';

define(['shared_helper', 'chai'], function (helper, chai) {
var rest;
var utils = helper.Utils;
var expect = chai.expect;

// RSL8
describe('rest/status', function () {
this.timeout(30 * 1000);

before(function (done) {
helper.setupApp(function (err) {
if (err) {
done(err);
return;
}
rest = helper.AblyRest();
done();
});
});

it('status0', function (done) {
var channel = rest.channels.get('status0');
channel.status(function (err, channelDetails) {
try {
expect(channelDetails.channelId).to.equal('status0');
expect(channelDetails.status.isActive).to.be.a('boolean');
var metrics = channelDetails.status.occupancy.metrics;
expect(metrics.connections).to.be.a('number');
expect(metrics.presenceConnections).to.be.a('number');
expect(metrics.presenceMembers).to.be.a('number');
expect(metrics.presenceSubscribers).to.be.a('number');
expect(metrics.publishers).to.be.a('number');
expect(metrics.subscribers).to.be.a('number');
done();
} catch (err) {
done(err);
}
});
});

if (typeof Promise !== 'undefined') {
it('statusPromise', function (done) {
var rest = helper.AblyRest({ promises: true });
var channel = rest.channels.get('statusPromise');
channel
.status()
.then(function (channelDetails) {
try {
expect(channelDetails.channelId).to.equal('statusPromise');
expect(channelDetails.status.isActive).to.be.a('boolean');
var metrics = channelDetails.status.occupancy.metrics;
expect(metrics.connections).to.be.a('number');
expect(metrics.presenceConnections).to.be.a('number');
expect(metrics.presenceMembers).to.be.a('number');
expect(metrics.presenceSubscribers).to.be.a('number');
expect(metrics.publishers).to.be.a('number');
expect(metrics.subscribers).to.be.a('number');
done();
} catch (err) {
done(err);
}
})
['catch'](function (err) {
done(err);
});
});
}
});
});

0 comments on commit 18132ad

Please sign in to comment.