feat(*): allow GRPC call options to be passed into operations

This commit is contained in:
Connor Peet 2017-10-21 10:29:00 -07:00
Родитель 8f0d60ef10
Коммит 8f2b7f73e1
14 изменённых файлов: 339 добавлений и 144 удалений

Просмотреть файл

@ -1,4 +1,4 @@
--<%= getCommentPrefixing(`rpc ${name}(`) %>
public <%= _.lowerFirst(name) %>(<%= req.empty ? '' : `req: ${requestTsType}` %>): Promise<<%= responseTsType %>> {
return this.client.exec('<%= service %>', '<%= _.lowerFirst(name) %>', <%= req.empty ? '{}' : 'req' %>);
public <%= _.lowerFirst(name) %>(<%= req.empty ? '' : `req: ${requestTsType}, ` %>options?: grpc.CallOptions): Promise<<%= responseTsType %>> {
return this.client.exec('<%= service %>', '<%= _.lowerFirst(name) %>', <%= req.empty ? '{}' : 'req' %>, options);
}

Просмотреть файл

@ -1,6 +1,6 @@
--<%= getCommentPrefixing(`rpc ${name}(`) %>
public <%= _.lowerFirst(name) %>(): Promise<IDuplexStream<<%= requestTsType %>, <%= responseTsType %>>> {
public <%= _.lowerFirst(name) %>(options?: grpc.CallOptions): Promise<IDuplexStream<<%= requestTsType %>, <%= responseTsType %>>> {
return this.client
.getConnection('<%= service %>')
.then(({ client, metadata }) => (<any> client).<%= _.lowerFirst(name) %>(metadata));
.then(({ client, metadata }) => (<any> client).<%= _.lowerFirst(name) %>(metadata, options));
}

Просмотреть файл

@ -1,4 +1,6 @@
--<%= getCommentPrefixing(`rpc ${name}(`) %>
public <%= _.lowerFirst(name) %>(<%= req.empty ? '' : `req: ${requestTsType}` %>): Promise<IResponseStream<<%= responseTsType %>>> {
return this.client.getConnection('<%= service %>').then(cnx => (<any> cnx.client).<%= _.lowerFirst(name) %>(<%= req.empty ? '{}' : 'req' %>));
public <%= _.lowerFirst(name) %>(<%= req.empty ? '' : `req: ${requestTsType}, ` %>options?: grpc.CallOptions): Promise<IResponseStream<<%= responseTsType %>>> {
return this.client
.getConnection('<%= service %>')
.then(({ client, metadata }) => (<any> client).<%= _.lowerFirst(name) %>(metadata, options, <%= req.empty ? '{}' : 'req' %>));
}

Просмотреть файл

@ -4,8 +4,16 @@
import * as grpc from 'grpc';
export interface ICallable {
exec(service: keyof typeof Services, method: string, params: object): Promise<any>;
getConnection(service: keyof typeof Services): Promise<{ client: grpc.Client, metadata: grpc.Metadata }>;
exec(
service: keyof typeof Services,
method: string,
params: object,
options?: grpc.CallOptions,
): Promise<any>;
getConnection(
service: keyof typeof Services,
): Promise<{ client: grpc.Client, metadata: grpc.Metadata }>;
}
export interface IResponseStream<T> {

Просмотреть файл

@ -1,3 +1,5 @@
import * as grpc from 'grpc';
import { Range } from './range';
import { AuthClient, Permission } from './rpc';
import { toBuffer } from './util';
@ -38,23 +40,26 @@ export class Role {
/**
* Creates the role in etcd.
*/
public create(): Promise<this> {
return this.client.roleAdd({ name: this.name }).then(() => this);
public create(options?: grpc.CallOptions): Promise<this> {
return this.client.roleAdd({ name: this.name }, options).then(() => this);
}
/**
* Deletes the role from etcd.
*/
public delete(): Promise<this> {
return this.client.roleDelete({ role: this.name }).then(() => this);
public delete(options?: grpc.CallOptions): Promise<this> {
return this.client.roleDelete({ role: this.name }, options).then(() => this);
}
/**
* Removes a permission from the role in etcd.
*/
public revoke(req: IPermissionRequest | IPermissionRequest[]): Promise<this> {
public revoke(
req: IPermissionRequest | IPermissionRequest[],
options?: grpc.CallOptions,
): Promise<this> {
if (req instanceof Array) {
return Promise.all(req.map(r => this.grant(r))).then(() => this);
return Promise.all(req.map(r => this.grant(r, options))).then(() => this);
}
const range = getRange(req);
@ -70,29 +75,35 @@ export class Role {
/**
* Grants one or more permissions to this role.
*/
public grant(req: IPermissionRequest | IPermissionRequest[]): Promise<this> {
public grant(
req: IPermissionRequest | IPermissionRequest[],
options?: grpc.CallOptions,
): Promise<this> {
if (req instanceof Array) {
return Promise.all(req.map(r => this.grant(r))).then(() => this);
}
const range = getRange(req);
return this.client
.roleGrantPermission({
name: this.name,
perm: {
permType: req.permission,
key: range.start,
range_end: range.end,
.roleGrantPermission(
{
name: this.name,
perm: {
permType: req.permission,
key: range.start,
range_end: range.end,
},
},
})
options,
)
.then(() => this);
}
/**
* Returns a list of permissions the role has.
*/
public permissions(): Promise<IPermissionResult[]> {
return this.client.roleGet({ role: this.name }).then(response => {
public permissions(options?: grpc.CallOptions): Promise<IPermissionResult[]> {
return this.client.roleGet({ role: this.name }, options).then(response => {
return response.perm.map(perm => ({
permission: perm.permType,
range: new Range(perm.key, perm.range_end),
@ -103,23 +114,23 @@ export class Role {
/**
* Grants a user access to the role.
*/
public addUser(user: string | User): Promise<this> {
public addUser(user: string | User, options?: grpc.CallOptions): Promise<this> {
if (user instanceof User) {
user = user.name;
}
return this.client.userGrantRole({ user, role: this.name }).then(() => this);
return this.client.userGrantRole({ user, role: this.name }, options).then(() => this);
}
/**
* Removes a user's access to the role.
*/
public removeUser(user: string | User): Promise<this> {
public removeUser(user: string | User, options?: grpc.CallOptions): Promise<this> {
if (user instanceof User) {
user = user.name;
}
return this.client.userRevokeRole({ name: user, role: this.name }).then(() => this);
return this.client.userRevokeRole({ name: user, role: this.name }, options).then(() => this);
}
}
@ -133,29 +144,29 @@ export class User {
/**
* Creates the user, with the provided password.
*/
public create(password: string): Promise<this> {
return this.client.userAdd({ name: this.name, password }).then(() => this);
public create(password: string, options?: grpc.CallOptions): Promise<this> {
return this.client.userAdd({ name: this.name, password }, options).then(() => this);
}
/**
* Changes the user's password.
*/
public setPassword(password: string): Promise<this> {
return this.client.userChangePassword({ name: this.name, password }).then(() => this);
public setPassword(password: string, options?: grpc.CallOptions): Promise<this> {
return this.client.userChangePassword({ name: this.name, password }, options).then(() => this);
}
/**
* Deletes the user from etcd.
*/
public delete(): Promise<this> {
return this.client.userDelete({ name: this.name }).then(() => this);
public delete(options?: grpc.CallOptions): Promise<this> {
return this.client.userDelete({ name: this.name }, options).then(() => this);
}
/**
* Returns a list of roles this user has.
*/
public roles(): Promise<Role[]> {
return this.client.userGet({ name: this.name }).then(res => {
public roles(options?: grpc.CallOptions): Promise<Role[]> {
return this.client.userGet({ name: this.name }, options).then(res => {
return res.roles.map(role => new Role(this.client, role));
});
}
@ -163,22 +174,22 @@ export class User {
/**
* Adds the user to a role.
*/
public addRole(role: string | Role): Promise<this> {
public addRole(role: string | Role, options?: grpc.CallOptions): Promise<this> {
if (role instanceof Role) {
role = role.name;
}
return this.client.userGrantRole({ user: this.name, role }).then(() => this);
return this.client.userGrantRole({ user: this.name, role }, options).then(() => this);
}
/**
* Removes the user's access to a role.
*/
public removeRole(role: string | Role): Promise<this> {
public removeRole(role: string | Role, options?: grpc.CallOptions): Promise<this> {
if (role instanceof Role) {
role = role.name;
}
return this.client.userRevokeRole({ name: this.name, role }).then(() => this);
return this.client.userRevokeRole({ name: this.name, role }, options).then(() => this);
}
}

Просмотреть файл

@ -1,3 +1,5 @@
import * as grpc from 'grpc';
import { Rangable, Range } from './range';
import * as RPC from './rpc';
import { NSApplicator, PromiseWrap, toBuffer } from './util';
@ -54,6 +56,7 @@ function assertWithin<T>(map: T, value: keyof T, thing: string) {
*/
export abstract class RangeBuilder<T> extends PromiseWrap<T> implements IOperation {
protected request: RPC.IRangeRequest = {};
protected callOptions: grpc.CallOptions | undefined;
constructor(protected readonly namespace: NSApplicator) {
super();
@ -107,6 +110,14 @@ export abstract class RangeBuilder<T> extends PromiseWrap<T> implements IOperati
return this;
}
/**
* Sets the GRPC call options for this request.
*/
public options(options: grpc.CallOptions | undefined): this {
this.callOptions = options;
return this;
}
/**
* Returns the request op for this builder, used in transactions.
*/
@ -163,7 +174,7 @@ export class SingleRangeBuilder extends RangeBuilder<string | null> {
* Runs the built request and returns the raw response from etcd.
*/
public exec(): Promise<RPC.IRangeResponse> {
return this.kv.range(this.namespace.applyToRequest(this.request));
return this.kv.range(this.namespace.applyToRequest(this.request), this.callOptions);
}
/**
@ -290,13 +301,15 @@ export class MultiRangeBuilder extends RangeBuilder<{ [key: string]: string }> {
* Runs the built request and returns the raw response from etcd.
*/
public exec(): Promise<RPC.IRangeResponse> {
return this.kv.range(this.namespace.applyToRequest(this.request)).then(res => {
for (let i = 0; i < res.kvs.length; i++) {
res.kvs[i].key = this.namespace.unprefix(res.kvs[i].key);
}
return this.kv
.range(this.namespace.applyToRequest(this.request), this.callOptions)
.then(res => {
for (let i = 0; i < res.kvs.length; i++) {
res.kvs[i].key = this.namespace.unprefix(res.kvs[i].key);
}
return res;
});
return res;
});
}
/**
@ -327,6 +340,7 @@ export class MultiRangeBuilder extends RangeBuilder<{ [key: string]: string }> {
*/
export class DeleteBuilder extends PromiseWrap<RPC.IDeleteRangeResponse> {
private request: RPC.IDeleteRangeRequest = {};
private callOptions: grpc.CallOptions | undefined;
constructor(private readonly kv: RPC.KVClient, private readonly namespace: NSApplicator) {
super();
@ -383,11 +397,20 @@ export class DeleteBuilder extends PromiseWrap<RPC.IDeleteRangeResponse> {
this.request.prev_kv = true;
return this.exec().then(res => res.prev_kvs);
}
/**
* Sets the GRPC call options for this request.
*/
public options(options: grpc.CallOptions | undefined): this {
this.callOptions = options;
return this;
}
/**
* exec runs the delete put request.
*/
public exec(): Promise<RPC.IDeleteRangeResponse> {
return this.kv.deleteRange(this.namespace.applyToRequest(this.request));
return this.kv.deleteRange(this.namespace.applyToRequest(this.request), this.callOptions);
}
/**
@ -412,6 +435,7 @@ export class DeleteBuilder extends PromiseWrap<RPC.IDeleteRangeResponse> {
*/
export class PutBuilder extends PromiseWrap<RPC.IPutResponse> {
private request: RPC.IPutRequest = {};
private callOptions: grpc.CallOptions | undefined;
constructor(
private readonly kv: RPC.KVClient,
@ -447,6 +471,14 @@ export class PutBuilder extends PromiseWrap<RPC.IPutResponse> {
return this;
}
/**
* Sets the GRPC call options for this request.
*/
public options(options: grpc.CallOptions | undefined): this {
this.callOptions = options;
return this;
}
/**
* getPrevious instructs etcd to *try* to get the previous value of the
* key before setting it. One may not always be available if a compaction
@ -471,7 +503,7 @@ export class PutBuilder extends PromiseWrap<RPC.IPutResponse> {
* exec runs the put request.
*/
public exec(): Promise<RPC.IPutResponse> {
return this.kv.put(this.namespace.applyToRequest(this.request));
return this.kv.put(this.namespace.applyToRequest(this.request), this.callOptions);
}
/**
@ -513,9 +545,18 @@ export class PutBuilder extends PromiseWrap<RPC.IPutResponse> {
*/
export class ComparatorBuilder {
private request: RPC.ITxnRequest = {};
private callOptions: grpc.CallOptions | undefined;
constructor(private readonly kv: RPC.KVClient, private readonly namespace: NSApplicator) {}
/**
* Sets the GRPC call options for this request.
*/
public options(options: grpc.CallOptions | undefined): this {
this.callOptions = options;
return this;
}
/**
* Adds a new clause to the transaction.
*/
@ -564,7 +605,7 @@ export class ComparatorBuilder {
* Runs the generated transaction and returns its result.
*/
public commit(): Promise<RPC.ITxnResponse> {
return this.kv.txn(this.request);
return this.kv.txn(this.request, this.callOptions);
}
/**

Просмотреть файл

@ -32,11 +32,12 @@ function removeProtocolPrefix(name: string) {
function runServiceCall(
client: grpc.Client,
metadata: grpc.Metadata,
options: grpc.CallOptions | undefined,
method: string,
payload: object,
): Promise<any> {
return new Promise((resolve, reject) => {
(<any>client)[method](payload, metadata, (err: Error | null, res: any) => {
(<any>client)[method](payload, metadata, options, (err: Error | null, res: any) => {
if (err) {
reject(castGrpcError(err));
} else {
@ -113,6 +114,7 @@ class Authenticator {
return runServiceCall(
new services.etcdserverpb.Auth(address, credentials),
new grpc.Metadata(),
undefined,
'authenticate',
{ name, password },
).then(res => res.token);
@ -201,13 +203,18 @@ export class ConnectionPool implements ICallable {
/**
* @override
*/
public exec(serviceName: keyof typeof Services, method: string, payload: object): Promise<any> {
public exec(
serviceName: keyof typeof Services,
method: string,
payload: object,
options?: grpc.CallOptions,
): Promise<any> {
if (this.mockImpl) {
return this.mockImpl.exec(serviceName, method, payload);
}
return this.getConnection(serviceName).then(({ host, client, metadata }) => {
return runServiceCall(client, metadata, method, payload)
return runServiceCall(client, metadata, options, method, payload)
.then(res => {
this.pool.succeed(host);
return res;
@ -215,7 +222,7 @@ export class ConnectionPool implements ICallable {
.catch(err => {
if (err instanceof EtcdInvalidAuthTokenError) {
this.authenticator.invalidateMetadata();
return this.exec(serviceName, method, payload);
return this.exec(serviceName, method, payload, options);
}
if (err instanceof GRPCGenericError) {
@ -223,7 +230,7 @@ export class ConnectionPool implements ICallable {
host.close();
if (this.pool.available().length && this.options.retry) {
return this.exec(serviceName, method, payload);
return this.exec(serviceName, method, payload, options);
}
}

Просмотреть файл

@ -1,4 +1,5 @@
import { EventEmitter } from 'events';
import * as grpc from 'grpc';
import { PutBuilder } from './builder';
import { ConnectionPool } from './connection-pool';
@ -82,6 +83,7 @@ export class Lease extends EventEmitter {
private readonly pool: ConnectionPool,
private readonly namespace: NSApplicator,
private ttl: number,
private readonly options?: grpc.CallOptions,
) {
super();
@ -90,7 +92,7 @@ export class Lease extends EventEmitter {
}
this.leaseID = this.client
.leaseGrant({ TTL: ttl })
.leaseGrant({ TTL: ttl }, this.options)
.then(res => {
this.state = State.Alive;
this.lastKeepAlive = Date.now();
@ -122,12 +124,12 @@ export class Lease extends EventEmitter {
* Revoke frees the lease from etcd. Keys that the lease owns will be
* evicted.
*/
public revoke(): Promise<void> {
public revoke(options: grpc.CallOptions | undefined = this.options): Promise<void> {
this.close();
return this.leaseID.then(id => {
if (!(id instanceof Error)) {
// if an error, we didn't grant in the first place
return this.client.leaseRevoke({ ID: id }).then(() => undefined);
return this.client.leaseRevoke({ ID: id }, options).then(() => undefined);
}
return undefined;
@ -148,8 +150,10 @@ export class Lease extends EventEmitter {
/**
* keepaliveOnce fires an immediate keepalive for the lease.
*/
public keepaliveOnce(): Promise<RPC.ILeaseKeepAliveResponse> {
return Promise.all([this.client.leaseKeepAlive(), this.grant()]).then(([stream, id]) => {
public keepaliveOnce(
options: grpc.CallOptions | undefined = this.options,
): Promise<RPC.ILeaseKeepAliveResponse> {
return Promise.all([this.client.leaseKeepAlive(options), this.grant()]).then(([stream, id]) => {
return new Promise<RPC.ILeaseKeepAliveResponse>((resolve, reject) => {
stream.on('data', resolve);
stream.on('error', err => reject(castGrpcError(err)));

Просмотреть файл

@ -1,6 +1,8 @@
import { EtcdLockFailedError } from './';
import * as grpc from 'grpc';
import { ComparatorBuilder, PutBuilder } from './builder';
import { ConnectionPool } from './connection-pool';
import { EtcdLockFailedError } from './errors';
import { Lease } from './lease';
import * as RPC from './rpc';
import { NSApplicator } from './util';
@ -33,6 +35,7 @@ import { NSApplicator } from './util';
export class Lock {
private leaseTTL = 30;
private lease: Lease | null;
private callOptions: grpc.CallOptions | undefined;
constructor(
private readonly pool: ConnectionPool,
@ -53,6 +56,14 @@ export class Lock {
return this;
}
/**
* Sets the GRPC call options for this request.
*/
public options(options: grpc.CallOptions): this {
this.callOptions = options;
return this;
}
/**
* Acquire attempts to acquire the lock, rejecting if it's unable to.
*/
@ -64,6 +75,7 @@ export class Lock {
return new ComparatorBuilder(kv, this.namespace)
.and(this.key, 'Create', '==', 0)
.then(new PutBuilder(kv, this.namespace, this.key).value('').lease(leaseID))
.options(this.callOptions)
.commit()
.then<this>(res => {
if (res.succeeded) {
@ -87,7 +99,7 @@ export class Lock {
throw new Error('Attempted to release a lock which was not acquired');
}
return this.lease.revoke();
return this.lease.revoke(this.callOptions);
}
/**

Просмотреть файл

@ -1,3 +1,5 @@
import * as grpc from 'grpc';
import * as Builder from './builder';
import { ConnectionPool } from './connection-pool';
import { Lease } from './lease';
@ -70,8 +72,8 @@ export class Namespace {
* automatically kept alive for you until it is revoked. See the
* documentation on the Lease class for some examples.
*/
public lease(ttl: number): Lease {
return new Lease(this.pool, this.nsApplicator, ttl);
public lease(ttl: number, options?: grpc.CallOptions): Lease {
return new Lease(this.pool, this.nsApplicator, ttl, options);
}
/**

Просмотреть файл

@ -4,7 +4,13 @@
import * as grpc from 'grpc';
export interface ICallable {
exec(service: keyof typeof Services, method: string, params: object): Promise<any>;
exec(
service: keyof typeof Services,
method: string,
params: object,
options?: grpc.CallOptions,
): Promise<any>;
getConnection(
service: keyof typeof Services,
): Promise<{ client: grpc.Client; metadata: grpc.Metadata }>;
@ -28,24 +34,27 @@ export class KVClient {
/**
* Range gets the keys in the range from the key-value store.
*/
public range(req: IRangeRequest): Promise<IRangeResponse> {
return this.client.exec('KV', 'range', req);
public range(req: IRangeRequest, options?: grpc.CallOptions): Promise<IRangeResponse> {
return this.client.exec('KV', 'range', req, options);
}
/**
* Put puts the given key into the key-value store.
* A put request increments the revision of the key-value store
* and generates one event in the event history.
*/
public put(req: IPutRequest): Promise<IPutResponse> {
return this.client.exec('KV', 'put', req);
public put(req: IPutRequest, options?: grpc.CallOptions): Promise<IPutResponse> {
return this.client.exec('KV', 'put', req, options);
}
/**
* DeleteRange deletes the given range from the key-value store.
* A delete request increments the revision of the key-value store
* and generates a delete event in the event history for every deleted key.
*/
public deleteRange(req: IDeleteRangeRequest): Promise<IDeleteRangeResponse> {
return this.client.exec('KV', 'deleteRange', req);
public deleteRange(
req: IDeleteRangeRequest,
options?: grpc.CallOptions,
): Promise<IDeleteRangeResponse> {
return this.client.exec('KV', 'deleteRange', req, options);
}
/**
* Txn processes multiple requests in a single transaction.
@ -53,16 +62,19 @@ export class KVClient {
* and generates events with the same revision for every completed request.
* It is not allowed to modify the same key several times within one txn.
*/
public txn(req: ITxnRequest): Promise<ITxnResponse> {
return this.client.exec('KV', 'txn', req);
public txn(req: ITxnRequest, options?: grpc.CallOptions): Promise<ITxnResponse> {
return this.client.exec('KV', 'txn', req, options);
}
/**
* Compact compacts the event history in the etcd key-value store. The key-value
* store should be periodically compacted or the event history will continue to grow
* indefinitely.
*/
public compact(req: ICompactionRequest): Promise<ICompactionResponse> {
return this.client.exec('KV', 'compact', req);
public compact(
req: ICompactionRequest,
options?: grpc.CallOptions,
): Promise<ICompactionResponse> {
return this.client.exec('KV', 'compact', req, options);
}
}
@ -75,10 +87,10 @@ export class WatchClient {
* for several watches at once. The entire event history can be watched starting from the
* last compaction revision.
*/
public watch(): Promise<IDuplexStream<IWatchRequest, IWatchResponse>> {
public watch(options?: grpc.CallOptions): Promise<IDuplexStream<IWatchRequest, IWatchResponse>> {
return this.client
.getConnection('Watch')
.then(({ client, metadata }) => (<any>client).watch(metadata));
.then(({ client, metadata }) => (<any>client).watch(metadata, options));
}
}
@ -89,35 +101,46 @@ export class LeaseClient {
* within a given time to live period. All keys attached to the lease will be expired and
* deleted if the lease expires. Each expired key generates a delete event in the event history.
*/
public leaseGrant(req: ILeaseGrantRequest): Promise<ILeaseGrantResponse> {
return this.client.exec('Lease', 'leaseGrant', req);
public leaseGrant(
req: ILeaseGrantRequest,
options?: grpc.CallOptions,
): Promise<ILeaseGrantResponse> {
return this.client.exec('Lease', 'leaseGrant', req, options);
}
/**
* LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted.
*/
public leaseRevoke(req: ILeaseRevokeRequest): Promise<ILeaseRevokeResponse> {
return this.client.exec('Lease', 'leaseRevoke', req);
public leaseRevoke(
req: ILeaseRevokeRequest,
options?: grpc.CallOptions,
): Promise<ILeaseRevokeResponse> {
return this.client.exec('Lease', 'leaseRevoke', req, options);
}
/**
* LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client
* to the server and streaming keep alive responses from the server to the client.
*/
public leaseKeepAlive(): Promise<IDuplexStream<ILeaseKeepAliveRequest, ILeaseKeepAliveResponse>> {
public leaseKeepAlive(
options?: grpc.CallOptions,
): Promise<IDuplexStream<ILeaseKeepAliveRequest, ILeaseKeepAliveResponse>> {
return this.client
.getConnection('Lease')
.then(({ client, metadata }) => (<any>client).leaseKeepAlive(metadata));
.then(({ client, metadata }) => (<any>client).leaseKeepAlive(metadata, options));
}
/**
* LeaseTimeToLive retrieves lease information.
*/
public leaseTimeToLive(req: ILeaseTimeToLiveRequest): Promise<ILeaseTimeToLiveResponse> {
return this.client.exec('Lease', 'leaseTimeToLive', req);
public leaseTimeToLive(
req: ILeaseTimeToLiveRequest,
options?: grpc.CallOptions,
): Promise<ILeaseTimeToLiveResponse> {
return this.client.exec('Lease', 'leaseTimeToLive', req, options);
}
/**
* LeaseLeases lists all existing leases.
*/
public leaseLeases(): Promise<ILeaseLeasesResponse> {
return this.client.exec('Lease', 'leaseLeases', {});
public leaseLeases(options?: grpc.CallOptions): Promise<ILeaseLeasesResponse> {
return this.client.exec('Lease', 'leaseLeases', {}, options);
}
}
@ -126,26 +149,35 @@ export class ClusterClient {
/**
* MemberAdd adds a member into the cluster.
*/
public memberAdd(req: IMemberAddRequest): Promise<IMemberAddResponse> {
return this.client.exec('Cluster', 'memberAdd', req);
public memberAdd(
req: IMemberAddRequest,
options?: grpc.CallOptions,
): Promise<IMemberAddResponse> {
return this.client.exec('Cluster', 'memberAdd', req, options);
}
/**
* MemberRemove removes an existing member from the cluster.
*/
public memberRemove(req: IMemberRemoveRequest): Promise<IMemberRemoveResponse> {
return this.client.exec('Cluster', 'memberRemove', req);
public memberRemove(
req: IMemberRemoveRequest,
options?: grpc.CallOptions,
): Promise<IMemberRemoveResponse> {
return this.client.exec('Cluster', 'memberRemove', req, options);
}
/**
* MemberUpdate updates the member configuration.
*/
public memberUpdate(req: IMemberUpdateRequest): Promise<IMemberUpdateResponse> {
return this.client.exec('Cluster', 'memberUpdate', req);
public memberUpdate(
req: IMemberUpdateRequest,
options?: grpc.CallOptions,
): Promise<IMemberUpdateResponse> {
return this.client.exec('Cluster', 'memberUpdate', req, options);
}
/**
* MemberList lists all the members in the cluster.
*/
public memberList(): Promise<IMemberListResponse> {
return this.client.exec('Cluster', 'memberList', {});
public memberList(options?: grpc.CallOptions): Promise<IMemberListResponse> {
return this.client.exec('Cluster', 'memberList', {}, options);
}
}
@ -154,46 +186,51 @@ export class MaintenanceClient {
/**
* Alarm activates, deactivates, and queries alarms regarding cluster health.
*/
public alarm(req: IAlarmRequest): Promise<IAlarmResponse> {
return this.client.exec('Maintenance', 'alarm', req);
public alarm(req: IAlarmRequest, options?: grpc.CallOptions): Promise<IAlarmResponse> {
return this.client.exec('Maintenance', 'alarm', req, options);
}
/**
* Status gets the status of the member.
*/
public status(): Promise<IStatusResponse> {
return this.client.exec('Maintenance', 'status', {});
public status(options?: grpc.CallOptions): Promise<IStatusResponse> {
return this.client.exec('Maintenance', 'status', {}, options);
}
/**
* Defragment defragments a member's backend database to recover storage space.
*/
public defragment(): Promise<IDefragmentResponse> {
return this.client.exec('Maintenance', 'defragment', {});
public defragment(options?: grpc.CallOptions): Promise<IDefragmentResponse> {
return this.client.exec('Maintenance', 'defragment', {}, options);
}
/**
* Hash computes the hash of the KV's backend.
* This is designed for testing; do not use this in production when there
* are ongoing transactions.
*/
public hash(): Promise<IHashResponse> {
return this.client.exec('Maintenance', 'hash', {});
public hash(options?: grpc.CallOptions): Promise<IHashResponse> {
return this.client.exec('Maintenance', 'hash', {}, options);
}
/**
* HashKV computes the hash of all MVCC keys up to a given revision.
*/
public hashKV(req: IHashKVRequest): Promise<IHashKVResponse> {
return this.client.exec('Maintenance', 'hashKV', req);
public hashKV(req: IHashKVRequest, options?: grpc.CallOptions): Promise<IHashKVResponse> {
return this.client.exec('Maintenance', 'hashKV', req, options);
}
/**
* Snapshot sends a snapshot of the entire backend from a member over a stream to a client.
*/
public snapshot(): Promise<IResponseStream<ISnapshotResponse>> {
return this.client.getConnection('Maintenance').then(cnx => (<any>cnx.client).snapshot({}));
public snapshot(options?: grpc.CallOptions): Promise<IResponseStream<ISnapshotResponse>> {
return this.client
.getConnection('Maintenance')
.then(({ client, metadata }) => (<any>client).snapshot(metadata, options, {}));
}
/**
* MoveLeader requests current leader node to transfer its leadership to transferee.
*/
public moveLeader(req: IMoveLeaderRequest): Promise<IMoveLeaderResponse> {
return this.client.exec('Maintenance', 'moveLeader', req);
public moveLeader(
req: IMoveLeaderRequest,
options?: grpc.CallOptions,
): Promise<IMoveLeaderResponse> {
return this.client.exec('Maintenance', 'moveLeader', req, options);
}
}
@ -202,104 +239,134 @@ export class AuthClient {
/**
* AuthEnable enables authentication.
*/
public authEnable(): Promise<IAuthEnableResponse> {
return this.client.exec('Auth', 'authEnable', {});
public authEnable(options?: grpc.CallOptions): Promise<IAuthEnableResponse> {
return this.client.exec('Auth', 'authEnable', {}, options);
}
/**
* AuthDisable disables authentication.
*/
public authDisable(): Promise<IAuthDisableResponse> {
return this.client.exec('Auth', 'authDisable', {});
public authDisable(options?: grpc.CallOptions): Promise<IAuthDisableResponse> {
return this.client.exec('Auth', 'authDisable', {}, options);
}
/**
* Authenticate processes an authenticate request.
*/
public authenticate(req: IAuthenticateRequest): Promise<IAuthenticateResponse> {
return this.client.exec('Auth', 'authenticate', req);
public authenticate(
req: IAuthenticateRequest,
options?: grpc.CallOptions,
): Promise<IAuthenticateResponse> {
return this.client.exec('Auth', 'authenticate', req, options);
}
/**
* UserAdd adds a new user.
*/
public userAdd(req: IAuthUserAddRequest): Promise<IAuthUserAddResponse> {
return this.client.exec('Auth', 'userAdd', req);
public userAdd(
req: IAuthUserAddRequest,
options?: grpc.CallOptions,
): Promise<IAuthUserAddResponse> {
return this.client.exec('Auth', 'userAdd', req, options);
}
/**
* UserGet gets detailed user information.
*/
public userGet(req: IAuthUserGetRequest): Promise<IAuthUserGetResponse> {
return this.client.exec('Auth', 'userGet', req);
public userGet(
req: IAuthUserGetRequest,
options?: grpc.CallOptions,
): Promise<IAuthUserGetResponse> {
return this.client.exec('Auth', 'userGet', req, options);
}
/**
* UserList gets a list of all users.
*/
public userList(): Promise<IAuthUserListResponse> {
return this.client.exec('Auth', 'userList', {});
public userList(options?: grpc.CallOptions): Promise<IAuthUserListResponse> {
return this.client.exec('Auth', 'userList', {}, options);
}
/**
* UserDelete deletes a specified user.
*/
public userDelete(req: IAuthUserDeleteRequest): Promise<IAuthUserDeleteResponse> {
return this.client.exec('Auth', 'userDelete', req);
public userDelete(
req: IAuthUserDeleteRequest,
options?: grpc.CallOptions,
): Promise<IAuthUserDeleteResponse> {
return this.client.exec('Auth', 'userDelete', req, options);
}
/**
* UserChangePassword changes the password of a specified user.
*/
public userChangePassword(
req: IAuthUserChangePasswordRequest,
options?: grpc.CallOptions,
): Promise<IAuthUserChangePasswordResponse> {
return this.client.exec('Auth', 'userChangePassword', req);
return this.client.exec('Auth', 'userChangePassword', req, options);
}
/**
* UserGrant grants a role to a specified user.
*/
public userGrantRole(req: IAuthUserGrantRoleRequest): Promise<IAuthUserGrantRoleResponse> {
return this.client.exec('Auth', 'userGrantRole', req);
public userGrantRole(
req: IAuthUserGrantRoleRequest,
options?: grpc.CallOptions,
): Promise<IAuthUserGrantRoleResponse> {
return this.client.exec('Auth', 'userGrantRole', req, options);
}
/**
* UserRevokeRole revokes a role of specified user.
*/
public userRevokeRole(req: IAuthUserRevokeRoleRequest): Promise<IAuthUserRevokeRoleResponse> {
return this.client.exec('Auth', 'userRevokeRole', req);
public userRevokeRole(
req: IAuthUserRevokeRoleRequest,
options?: grpc.CallOptions,
): Promise<IAuthUserRevokeRoleResponse> {
return this.client.exec('Auth', 'userRevokeRole', req, options);
}
/**
* RoleAdd adds a new role.
*/
public roleAdd(req: IAuthRoleAddRequest): Promise<IAuthRoleAddResponse> {
return this.client.exec('Auth', 'roleAdd', req);
public roleAdd(
req: IAuthRoleAddRequest,
options?: grpc.CallOptions,
): Promise<IAuthRoleAddResponse> {
return this.client.exec('Auth', 'roleAdd', req, options);
}
/**
* RoleGet gets detailed role information.
*/
public roleGet(req: IAuthRoleGetRequest): Promise<IAuthRoleGetResponse> {
return this.client.exec('Auth', 'roleGet', req);
public roleGet(
req: IAuthRoleGetRequest,
options?: grpc.CallOptions,
): Promise<IAuthRoleGetResponse> {
return this.client.exec('Auth', 'roleGet', req, options);
}
/**
* RoleList gets lists of all roles.
*/
public roleList(): Promise<IAuthRoleListResponse> {
return this.client.exec('Auth', 'roleList', {});
public roleList(options?: grpc.CallOptions): Promise<IAuthRoleListResponse> {
return this.client.exec('Auth', 'roleList', {}, options);
}
/**
* RoleDelete deletes a specified role.
*/
public roleDelete(req: IAuthRoleDeleteRequest): Promise<IAuthRoleDeleteResponse> {
return this.client.exec('Auth', 'roleDelete', req);
public roleDelete(
req: IAuthRoleDeleteRequest,
options?: grpc.CallOptions,
): Promise<IAuthRoleDeleteResponse> {
return this.client.exec('Auth', 'roleDelete', req, options);
}
/**
* RoleGrantPermission grants a permission of a specified key or range to a specified role.
*/
public roleGrantPermission(
req: IAuthRoleGrantPermissionRequest,
options?: grpc.CallOptions,
): Promise<IAuthRoleGrantPermissionResponse> {
return this.client.exec('Auth', 'roleGrantPermission', req);
return this.client.exec('Auth', 'roleGrantPermission', req, options);
}
/**
* RoleRevokePermission revokes a key or range permission of a specified role.
*/
public roleRevokePermission(
req: IAuthRoleRevokePermissionRequest,
options?: grpc.CallOptions,
): Promise<IAuthRoleRevokePermissionResponse> {
return this.client.exec('Auth', 'roleRevokePermission', req);
return this.client.exec('Auth', 'roleRevokePermission', req, options);
}
}

Просмотреть файл

@ -1,4 +1,5 @@
import BigNumber from 'bignumber.js';
import * as grpc from 'grpc';
import * as Builder from './builder';
import { ClientRuntimeError, STMConflictError } from './errors';
@ -55,6 +56,11 @@ export interface ISTMOptions {
* Isolation level for the transaction. Defaults to SerializableSnapshot.
*/
isolation: Isolation;
/**
* Options to pass into the STM transaction's commit.
*/
callOptions?: grpc.CallOptions;
}
/**
@ -505,10 +511,13 @@ export class SoftwareTransaction {
this.tx.writeSet.addChanges(cmp);
return cmp.commit().then(result => {
if (!result.succeeded) {
throw new STMConflictError();
}
});
return cmp
.options(this.options.callOptions)
.commit()
.then(result => {
if (!result.succeeded) {
throw new STMConflictError();
}
});
}
}

33
src/types/grpc.d.ts поставляемый
Просмотреть файл

@ -14,6 +14,39 @@ export class Service {
private constructor();
}
/**
* The deadline of an operation. If it is a date, the deadline is reached at
* the date and time specified. If it is a finite number, it is treated as
* a number of milliseconds since the Unix Epoch. If it is Infinity, the
* deadline will never be reached. If it is -Infinity, the deadline has already
* passed.
*/
export type Deadline = number | Date;
/**
* Options that can be set on a call.
*/
export interface CallOptions {
/**
* The deadline for the entire call to complete.
*/
deadline?: Deadline;
/**
* Server hostname to set on the call. Only meaningful if different from
* the server address used to construct the client.
*/
host?: string;
/**
* Indicates which properties of a parent call should propagate to this
* call. Bitwise combination of flags in `grpc.propagate`.
*/
propagate_flags: number;
/**
* The credentials that should be used to make this particular call.
*/
credentials: CallCredentials;
}
/**
* Describes some generic GRPC call or service function. This is super generic,
* you'll probably want to override or cast these based on your specific typing.

Просмотреть файл

@ -6,7 +6,6 @@
"rules": {
// Basic
"no-multiline-string": false,
"max-file-line-count": [true, 600],
"jsdoc-format": true,
"cyclomatic-complexity": [true, 20],
"no-default-export": false,