Skip to content

Commit 63f33d9

Browse files
committed
feat(middleware-user-agent): add retry mode metrics
1 parent 6ea2607 commit 63f33d9

File tree

5 files changed

+38
-15
lines changed

5 files changed

+38
-15
lines changed

packages/middleware-retry/src/defaultStrategy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export class StandardRetryStrategy implements RetryStrategy {
7474
private retryDecider: RetryDecider;
7575
private delayDecider: DelayDecider;
7676
private retryQuota: RetryQuota;
77+
public readonly mode = DEFAULT_RETRY_MODE;
7778

7879
constructor(private readonly maxAttemptsProvider: Provider<number>, options?: StandardRetryStrategyOptions) {
7980
this.retryDecider = options?.retryDecider ?? defaultRetryDecider;

packages/middleware-retry/src/retryMiddleware.spec.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FinalizeHandlerArguments, MiddlewareStack, RetryStrategy } from "@aws-sdk/types";
1+
import { FinalizeHandlerArguments, HandlerExecutionContext, MiddlewareStack, RetryStrategy } from "@aws-sdk/types";
22

33
import { getRetryPlugin, retryMiddleware, retryMiddlewareOptions } from "./retryMiddleware";
44

@@ -37,15 +37,21 @@ describe("retryMiddleware", () => {
3737
request: {},
3838
};
3939
const mockRetryStrategy = {
40+
mode: "mock",
4041
maxAttempts,
4142
retry: jest.fn(),
4243
};
44+
const context: HandlerExecutionContext = {};
4345

4446
await retryMiddleware({
4547
maxAttempts: () => Promise.resolve(maxAttempts),
4648
retryStrategy: mockRetryStrategy,
47-
})(next)(args as FinalizeHandlerArguments<any>);
49+
})(
50+
next,
51+
context
52+
)(args as FinalizeHandlerArguments<any>);
4853
expect(mockRetryStrategy.retry).toHaveBeenCalledTimes(1);
4954
expect(mockRetryStrategy.retry).toHaveBeenCalledWith(next, args);
55+
expect(context.userAgent).toContainEqual(["cfg/retry-mode", "mock"]);
5056
});
5157
});

packages/middleware-retry/src/retryMiddleware.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,23 @@ import {
44
FinalizeHandlerArguments,
55
FinalizeHandlerOutput,
66
FinalizeRequestHandlerOptions,
7+
HandlerExecutionContext,
78
MetadataBearer,
89
Pluggable,
910
} from "@aws-sdk/types";
1011

1112
import { RetryResolvedConfig } from "./configurations";
1213

1314
export const retryMiddleware = (options: RetryResolvedConfig) => <Output extends MetadataBearer = MetadataBearer>(
14-
next: FinalizeHandler<any, Output>
15+
next: FinalizeHandler<any, Output>,
16+
context: HandlerExecutionContext
1517
): FinalizeHandler<any, Output> => async (
1618
args: FinalizeHandlerArguments<any>
17-
): Promise<FinalizeHandlerOutput<Output>> => options.retryStrategy.retry(next, args);
19+
): Promise<FinalizeHandlerOutput<Output>> => {
20+
if (options?.retryStrategy?.mode)
21+
context.userAgent = [...(context.userAgent || []), ["cfg/retry-mode", options.retryStrategy.mode]];
22+
return options.retryStrategy.retry(next, args);
23+
};
1824

1925
export const retryMiddlewareOptions: FinalizeRequestHandlerOptions & AbsoluteLocation = {
2026
name: "retryMiddleware",

packages/middleware-user-agent/src/user-agent-middleware.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { HttpRequest } from "@aws-sdk/protocol-http";
22
import {
3-
BuildHandler,
4-
BuildHandlerArguments,
5-
BuildHandlerOptions,
6-
BuildHandlerOutput,
3+
FinalizeHandler,
4+
FinalizeHandlerArguments,
5+
FinalizeHandlerOutput,
76
HandlerExecutionContext,
87
MetadataBearer,
98
Pluggable,
9+
RelativeMiddlewareOptions,
1010
UserAgentPair,
1111
} from "@aws-sdk/types";
1212

@@ -26,9 +26,9 @@ import { SPACE, UA_ESCAPE_REGEX, USER_AGENT, X_AMZ_USER_AGENT } from "./constant
2626
* agent.
2727
*/
2828
export const userAgentMiddleware = (options: UserAgentResolvedConfig) => <Output extends MetadataBearer>(
29-
next: BuildHandler<any, any>,
29+
next: FinalizeHandler<any, any>,
3030
context: HandlerExecutionContext
31-
): BuildHandler<any, any> => async (args: BuildHandlerArguments<any>): Promise<BuildHandlerOutput<Output>> => {
31+
): FinalizeHandler<any, any> => async (args: FinalizeHandlerArguments<any>): Promise<FinalizeHandlerOutput<Output>> => {
3232
const { request } = args;
3333
if (!HttpRequest.isInstance(request)) return next(args);
3434
const { headers } = request;
@@ -57,7 +57,7 @@ export const userAgentMiddleware = (options: UserAgentResolvedConfig) => <Output
5757
* User agent name may include prefix like `md/`, `api/`, `os/` etc., we should not escape the `/` after the prefix.
5858
* @private
5959
*/
60-
export const escapeUserAgent = ([name, version]: UserAgentPair): string => {
60+
const escapeUserAgent = ([name, version]: UserAgentPair): string => {
6161
const prefixSeparatorIndex = name.indexOf("/");
6262
const prefix = name.substring(0, prefixSeparatorIndex); // If no prefix, prefix is just ""
6363
const uaName = name.substring(prefixSeparatorIndex + 1);
@@ -67,14 +67,15 @@ export const escapeUserAgent = ([name, version]: UserAgentPair): string => {
6767
.join("/");
6868
};
6969

70-
export const getUserAgentMiddlewareOptions: BuildHandlerOptions = {
70+
export const getUserAgentMiddlewareOptions: RelativeMiddlewareOptions = {
7171
name: "getUserAgentMiddleware",
72-
step: "build",
72+
relation: "before",
73+
toMiddleware: "awsAuthMiddleware",
7374
tags: ["SET_USER_AGENT", "USER_AGENT"],
7475
};
7576

7677
export const getUserAgentPlugin = (config: UserAgentResolvedConfig): Pluggable<any, any> => ({
7778
applyToStack: (clientStack) => {
78-
clientStack.add(userAgentMiddleware(config), getUserAgentMiddlewareOptions);
79+
clientStack.addRelativeTo(userAgentMiddleware(config), getUserAgentMiddlewareOptions);
7980
},
8081
});

packages/types/src/util.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { Endpoint } from "./http";
2-
import { FinalizeHandler, FinalizeHandlerArguments, FinalizeHandlerOutput } from "./middleware";
2+
import {
3+
FinalizeHandler,
4+
FinalizeHandlerArguments,
5+
FinalizeHandlerOutput,
6+
HandlerExecutionContext,
7+
} from "./middleware";
38
import { MetadataBearer } from "./response";
49

510
/**
@@ -53,6 +58,10 @@ export interface BodyLengthCalculator {
5358
* Interface that specifies the retry behavior
5459
*/
5560
export interface RetryStrategy {
61+
/**
62+
* The retry mode describing how the retry strategy control the traffic flow.
63+
*/
64+
mode?: string;
5665
/**
5766
* the retry behavior the will invoke the next handler and handle the retry accordingly.
5867
* This function should also update the $metadata from the response accordingly.

0 commit comments

Comments
 (0)