Skip to content

Commit a69a7c9

Browse files
committed
Add AckDeadlineRenewer and AckDeadlineRenewerImpl classes
1 parent 235152e commit a69a7c9

File tree

6 files changed

+1215
-0
lines changed

6 files changed

+1215
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.pubsub;
18+
19+
import static com.google.common.base.Preconditions.checkArgument;
20+
21+
import com.google.common.base.MoreObjects;
22+
23+
import java.io.Serializable;
24+
import java.util.Objects;
25+
26+
/**
27+
* Parameters for configuring automatic ack deadline renewals with an exponential backoff. The first
28+
* time the ack deadline is renewed for a pulled message, its value is set to
29+
* {@link #initialDeadlineSeconds()}. For each subsequent ack deadline renewal, the ack deadline is
30+
* calculated as:
31+
*
32+
* <p>{@code deadlineBackoffFactor ^ renewals * initialDeadlineSeconds} but would be upper-bounded
33+
* to {@code maxDeadlineSeconds}
34+
*/
35+
public final class AckDeadlineRenewParams implements Serializable {
36+
37+
private static final long serialVersionUID = -8142363212304296426L;
38+
39+
public static final int DEFAULT_INITIAL_DEADLINE_SECONDS = 10;
40+
public static final int DEFAULT_MAX_DEADLINED_SECONDS = 80;
41+
public static final double DEFAULT_DEADLINE_BACKOFF_FACTOR = 2.0;
42+
43+
private final int initialDeadlineSeconds;
44+
private final int maxDeadlineSeconds;
45+
private final double deadlineBackoffFactor;
46+
47+
private static final AckDeadlineRenewParams DEFAULT_INSTANCE =
48+
new AckDeadlineRenewParams(new Builder());
49+
private static final AckDeadlineRenewParams NO_BACKOFF = builder()
50+
.maxDeadlineSeconds(DEFAULT_INITIAL_DEADLINE_SECONDS)
51+
.deadlineBackoffFactor(1)
52+
.initialDeadlineSeconds(DEFAULT_INITIAL_DEADLINE_SECONDS)
53+
.build();
54+
55+
/**
56+
* {@code AckDeadlineRenewParams} builder.
57+
*/
58+
public static final class Builder {
59+
60+
private int initialDeadlineSeconds;
61+
private int maxDeadlineSeconds;
62+
private double deadlineBackoffFactor;
63+
64+
private Builder() {
65+
this.initialDeadlineSeconds = DEFAULT_INITIAL_DEADLINE_SECONDS;
66+
this.maxDeadlineSeconds = DEFAULT_MAX_DEADLINED_SECONDS;
67+
this.deadlineBackoffFactor = DEFAULT_DEADLINE_BACKOFF_FACTOR;
68+
}
69+
70+
Builder(AckDeadlineRenewParams renewParams) {
71+
this.initialDeadlineSeconds = renewParams.initialDeadlineSeconds;
72+
this.maxDeadlineSeconds = renewParams.maxDeadlineSeconds;
73+
this.deadlineBackoffFactor = renewParams.deadlineBackoffFactor;
74+
}
75+
76+
/**
77+
* Sets the initial deadline value, used the first time the ack deadline is renewed for a pulled
78+
* message. This value must be &gt= 10 seconds.
79+
*
80+
* @param initialDeadlineSeconds the initial deadline value, in seconds
81+
* @return the Builder for chaining
82+
*/
83+
public Builder initialDeadlineSeconds(int initialDeadlineSeconds) {
84+
this.initialDeadlineSeconds = initialDeadlineSeconds;
85+
return this;
86+
}
87+
88+
/**
89+
* Sets the maximum deadline value. This value must be greater or equal to the value set for
90+
* {@link #initialDeadlineSeconds(int)}.
91+
*
92+
* @param maxDeadlineSeconds the maximum deadline value, in seconds
93+
* @return the Builder for chaining
94+
*/
95+
public Builder maxDeadlineSeconds(int maxDeadlineSeconds) {
96+
this.maxDeadlineSeconds = maxDeadlineSeconds;
97+
return this;
98+
}
99+
100+
/**
101+
* Sets the deadline backoff factor, used to compute deadline renewal values after the initial
102+
* one. This value must be &gt= 1.
103+
*
104+
* @param deadlineBackoffFactor the backoff factor
105+
* @return the Builder for chaining
106+
*/
107+
public Builder deadlineBackoffFactor(double deadlineBackoffFactor) {
108+
this.deadlineBackoffFactor = deadlineBackoffFactor;
109+
return this;
110+
}
111+
112+
/**
113+
* Create an instance of {@code AckDeadlineRenewParams} with the parameters set in this builder.
114+
*
115+
* @return a new instance of {@code AckDeadlineRenewParams}
116+
*/
117+
public AckDeadlineRenewParams build() {
118+
return new AckDeadlineRenewParams(this);
119+
}
120+
}
121+
122+
private AckDeadlineRenewParams(Builder builder) {
123+
initialDeadlineSeconds = builder.initialDeadlineSeconds;
124+
maxDeadlineSeconds = builder.maxDeadlineSeconds;
125+
deadlineBackoffFactor = builder.deadlineBackoffFactor;
126+
checkArgument(initialDeadlineSeconds >= 10, "Initial deadline must be >= 10 seconds");
127+
checkArgument(maxDeadlineSeconds >= initialDeadlineSeconds,
128+
"Max deadline must be greater or equal to the initial deadline");
129+
checkArgument(deadlineBackoffFactor >= 1.0, "Deadline backoff factor must be >= 1");
130+
}
131+
132+
/**
133+
* Returns an {@code AckDeadlineRenewParams} object with default values: initial deadline is
134+
* {@value DEFAULT_INITIAL_DEADLINE_SECONDS} seconds, max deadline is
135+
* {@value DEFAULT_MAX_DEADLINED_SECONDS} seconds and the backoff factor is
136+
* {@value DEFAULT_DEADLINE_BACKOFF_FACTOR}.
137+
*/
138+
public static AckDeadlineRenewParams defaultInstance() {
139+
return DEFAULT_INSTANCE;
140+
}
141+
142+
/**
143+
* Returns an {@code AckDeadlineRenewParams} object that does no backoff, deadline is always set
144+
* to 10 seconds.
145+
*/
146+
public static AckDeadlineRenewParams noBackoff() {
147+
return NO_BACKOFF;
148+
}
149+
150+
/**
151+
* Returns the initial deadline value, used the first time the ack deadline is renewed for a
152+
* pulled message.
153+
*/
154+
public int initialDeadlineSeconds() {
155+
return initialDeadlineSeconds;
156+
}
157+
158+
/**
159+
* Returns the maximum deadline value.
160+
*/
161+
public int maxDeadlineSeconds() {
162+
return maxDeadlineSeconds;
163+
}
164+
165+
/**
166+
* Sets the deadline backoff factor, used to compute deadline renewal values after the initial
167+
* one.
168+
*/
169+
public double deadlineBackoffFactor() {
170+
return deadlineBackoffFactor;
171+
}
172+
173+
@Override
174+
public int hashCode() {
175+
return Objects.hash(initialDeadlineSeconds, maxDeadlineSeconds, deadlineBackoffFactor);
176+
}
177+
178+
@Override
179+
public boolean equals(Object obj) {
180+
if (obj == this) {
181+
return true;
182+
}
183+
if (!(obj instanceof AckDeadlineRenewParams)) {
184+
return false;
185+
}
186+
AckDeadlineRenewParams other = (AckDeadlineRenewParams) obj;
187+
return initialDeadlineSeconds == other.initialDeadlineSeconds
188+
&& maxDeadlineSeconds == other.maxDeadlineSeconds
189+
&& deadlineBackoffFactor == other.deadlineBackoffFactor;
190+
}
191+
192+
@Override
193+
public String toString() {
194+
return MoreObjects.toStringHelper(this)
195+
.add("initialDeadlineSeconds", initialDeadlineSeconds)
196+
.add("maxDeadlineSeconds", maxDeadlineSeconds)
197+
.add("deadlineBackoffFactor", deadlineBackoffFactor).toString();
198+
}
199+
200+
/**
201+
* Returns a builder for {@code AckDeadlineRenewParams} objects.
202+
*/
203+
public static Builder builder() {
204+
return new Builder();
205+
}
206+
207+
/**
208+
* Returns a builder for the current {@code AckDeadlineRenewParams} object.
209+
*/
210+
public Builder toBuilder() {
211+
return new Builder(this);
212+
}
213+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.pubsub;
18+
19+
/**
20+
* Interface for an automatic ack deadline renewer. An ack deadline renewer automatically renews
21+
* the acknowledge deadline of messages added to it (via {@link #add(String, String)} or
22+
* {@link #add(String, Iterable)}. The acknowledge deadlines of added messages are renewed until
23+
* the messages are explicitly removed using either {@link #remove(String, String)} or
24+
* {@link #remove(String, Iterable)}.
25+
*/
26+
interface AckDeadlineRenewer extends AutoCloseable {
27+
28+
/**
29+
* Adds a new message for which the acknowledge deadline should be automatically renewed. The
30+
* message is identified by the subscription from which it was pulled and its acknowledge id.
31+
* Auto-renewal will take place until the message is removed (see {@link #remove(String, String)}
32+
* or {@link #remove(String, Iterable)}).
33+
*
34+
* @param subscription the subscription from which the message has been pulled
35+
* @param ackId the message's acknowledge id
36+
*/
37+
void add(String subscription, String ackId);
38+
39+
/**
40+
* Adds new messages for which the acknowledge deadlined should be automatically renewed. The
41+
* messages are identified by the subscription from which they were pulled and their
42+
* acknowledge id. Auto-renewal will take place until the messages are removed (see
43+
* {@link #remove(String, String)} or {@link #remove(String, Iterable)}).
44+
*
45+
* @param subscription the subscription from which the messages have been pulled
46+
* @param ackIds the acknowledge ids of the messages
47+
*/
48+
void add(String subscription, Iterable<String> ackIds);
49+
50+
/**
51+
* Removes a message from this {@code AckDeadlineRenewer}. The message is identified by the
52+
* subscription from which it was pulled and its acknowledge id. Once the message is removed from
53+
* this {@code AckDeadlineRenewer}, automated ack deadline renewals will stop.
54+
*
55+
* @param subscription the subscription from which the message has been pulled
56+
* @param ackId the message's acknowledge id
57+
*/
58+
void remove(String subscription, String ackId);
59+
60+
/**
61+
* Removes messages from this {@code AckDeadlineRenewer}. The messages are identified by the
62+
* subscription from which they were pulled and their acknowledge id. Once the messages are
63+
* removed from this {@code AckDeadlineRenewer}, automated ack deadline renewals will stop.
64+
*
65+
* @param subscription the subscription from which the message has been pulled
66+
* @param ackIds the acknowledge ids of the messages
67+
*/
68+
void remove(String subscription, Iterable<String> ackIds);
69+
}

0 commit comments

Comments
 (0)