aboutsummaryrefslogtreecommitdiffstats
path: root/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/FeedParams.java
blob: 4adf3912dbdd39605b52e2896c3e4d8ab3ba0e0d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.http.client.config;

import com.google.common.annotations.Beta;
import net.jcip.annotations.Immutable;

import java.util.concurrent.TimeUnit;

/**
 * Parameters given to a {@link com.yahoo.vespa.http.client.SessionFactory}
 * when creating {@link com.yahoo.vespa.http.client.Session}s. This class is immutable
 * and has no public constructor - to instantiate one, use a {@link Builder}.

 * @author Einar M R Rosenvinge
 */
@Immutable
public final class FeedParams {

    public boolean getDenyIfBusyV3() {
        return denyIfBusyV3;
    }

    public long getMaxSleepTimeMs() {
        return maxSleepTimeMs;
    }

    public boolean getSilentUpgrade() { return silentUpgrade; }

    /**
     * Enumeration of data formats that are acceptable by the OutputStream
     * returned by {@link com.yahoo.vespa.http.client.Session#stream(CharSequence)}.
     */
    public enum DataFormat {
        /** UTF-8-encoded XML. Preamble is not necessary. */
        XML_UTF8,
        JSON_UTF8
    }
    /**
     * Mutable class used to instantiate a {@link FeedParams}.
     */
    public static final class Builder {
        private DataFormat dataFormat = DataFormat.JSON_UTF8;
        private long serverTimeout = TimeUnit.SECONDS.toMillis(180);
        private long clientTimeout = TimeUnit.SECONDS.toMillis(20);
        private String route = null;
        private int maxChunkSizeBytes = 50 * 1024;
        private int maxInFlightRequests = 5000;
        private long localQueueTimeOut = 180000;
        private String priority = null;
        private boolean denyIfBusyV3 = true;
        private long maxSleepTimeMs = 3000;
        private boolean silentUpgrade = true;

        /**
         * Make server not throw 4xx/5xx for situations that are normal during upgrade as this can esily mask
         * other problems. This feature need to be supported on server side to work, but it is still safe
         * to enable it, even if server does not yet support it. As of Nov 22 2016 it is not yet implemented on
         * the server side.
         * @param silentUpgrade true for reducing "false" 4xx/5xx.
         * @return this, for chaining
         */
        @Beta
        public Builder withSilentUpgrade(boolean silentUpgrade) {
            this.silentUpgrade = silentUpgrade;
            return this;
        }

        /**
         * When throttling the load due to transient errors on gateway, what is the most time to wait between
         * requests per thread. Only active for V3 protocol.
         * @param ms max with time
         * @return this, for chaining
         */
        public Builder setMaxSleepTimeMs(long ms) {
            this.maxSleepTimeMs = ms;
            return this;
        }

        /**
         * If this is set to false, the gateway will block threads until messagebus can send the message.
         * If true, the gateway will exit and fail the request early if there are many threads already
         * blocked.
         * @param value true to reduce number of blocked threads in gateway.
         * @return this, for chaining
         */
        public Builder setDenyIfBusyV3(boolean value) {
            denyIfBusyV3 = value;
            return this;
        }

        /**
         * Sets the data format to be used.
         *
         * @param dataFormat the data format to be used.
         * @see DataFormat
         * @return this, for chaining
         */
        public Builder setDataFormat(DataFormat dataFormat) {
            this.dataFormat = dataFormat;
            return this;
        }

        /**
         * Sets a route to be used for all Clusters, unless overridden on a per-cluster basis
         * in {@link com.yahoo.vespa.http.client.config.Cluster#getRoute()}.
         *
         * @param route a route to be used for all Clusters.
         * @return this, for chaining
         */
        public Builder setRoute(String route) {
            this.route = route;
            return this;
        }

        /**
         * Sets the server-side timeout of each operation - i.e. the timeout used by
         * the server endpoint for operations going over the message bus protocol into
         * Vespa.
         *
         * Note that the TOTAL timeout of any one operation in this API would be
         * {@link #getServerTimeout(java.util.concurrent.TimeUnit)} +
         * {@link #getClientTimeout(java.util.concurrent.TimeUnit)},
         * after which {@link com.yahoo.vespa.http.client.Session#results()} is guaranteed
         * to produce a Result.
         *
         * @param serverTimeout timeout value
         * @param unit unit of timeout value
         * @return this, for chaining
         */
        public Builder setServerTimeout(long serverTimeout, TimeUnit unit) {
            if (serverTimeout <= 0L) {
                throw new IllegalArgumentException("Server timeout cannot be zero or negative.");
            }
            this.serverTimeout = unit.toMillis(serverTimeout);
            return this;
        }

        /**
         * Sets the client-side timeout for each operation.&nbsp;If BOTH the server-side
         * timeout AND this timeout has passed, {@link com.yahoo.vespa.http.client.Session}
         * will synthesize a {@link com.yahoo.vespa.http.client.Result}.
         *
         * Note that the TOTAL timeout of any one operation in this API would be
         * {@link #getServerTimeout(java.util.concurrent.TimeUnit)} +
         * {@link #getClientTimeout(java.util.concurrent.TimeUnit)},
         * after which {@link com.yahoo.vespa.http.client.Session#results()} is guaranteed
         * to produce a Result.
         *
         * @param clientTimeout timeout value
         * @param unit unit of timeout value
         * @return this, for chaining
         */
        public Builder setClientTimeout(long clientTimeout, TimeUnit unit) {
            if (clientTimeout <= 0L) {
                throw new IllegalArgumentException("Client timeout cannot be zero or negative.");
            }
            this.clientTimeout = unit.toMillis(clientTimeout);
            return this;
        }

        /**
         * Sets the maximum number of bytes of document data to send per HTTP request.
         *
         * @param maxChunkSizeBytes max number of bytes per HTTP request.
         * @return this, for chaining
         */
        public Builder setMaxChunkSizeBytes(int maxChunkSizeBytes) {
            this.maxChunkSizeBytes = maxChunkSizeBytes;
            return this;
        }

        /**
         * Sets the maximum number of operations to be in-flight.
         * @param maxInFlightRequests max number of operations.
         * @return this, for chaining
         */
        public Builder setMaxInFlightRequests(int maxInFlightRequests) {
            this.maxInFlightRequests = maxInFlightRequests;
            return this;
        }

        public Builder setLocalQueueTimeOut(long timeOutMs) {
            this.localQueueTimeOut = timeOutMs;
            return this;
        }

        /**
         * Sets the messagebus priority. The allowed values are HIGHEST, VERY_HIGH, HIGH_[1-3],
         * NORMAL_[1-6], LOW_[1-3], VERY_LOW, and LOWEST..
         * @param priority messagebus priority of this message.
         * @return this, for chaining
         */
        public Builder setPriority(String priority) {
            if (priority == null) {
                return this;
            }
            switch (priority) {
                case "HIGHEST":
                case "VERY_HIGH":
                case "HIGH_1":
                case "HIGH_2":
                case "HIGH_3":
                case "NORMAL_1":
                case "NORMAL_2":
                case "NORMAL_3":
                case "NORMAL_4":
                case "NORMAL_5":
                case "NORMAL_6":
                case "LOW_1":
                case "LOW_2":
                case "LOW_3":
                case "VERY_LOW":
                case "LOWEST":
                    this.priority = priority;
                    return this;
                default:
                    throw new IllegalArgumentException("Unknown value for priority: " + priority
                            + " Allowed values are HIGHEST, VERY_HIGH, HIGH_[1-3], " +
                            "NORMAL_[1-6], LOW_[1-3], VERY_LOW, and LOWEST.");
            }
        }

        /**
         * Instantiates a {@link FeedParams}.
         *
         * @return a FeedParams object with the parameters of this Builder
         */
        public FeedParams build() {
            return new FeedParams(
                    dataFormat, serverTimeout, clientTimeout, route,
                    maxChunkSizeBytes, maxInFlightRequests, localQueueTimeOut, priority,
                    denyIfBusyV3, maxSleepTimeMs, silentUpgrade);
        }

        public long getClientTimeout(TimeUnit unit) {
            return unit.convert(clientTimeout, TimeUnit.MILLISECONDS);
        }

        public long getServerTimeout(TimeUnit unit) {
            return unit.convert(serverTimeout, TimeUnit.MILLISECONDS);
        }

        public String getRoute() {
            return route;
        }

        public DataFormat getDataFormat() {
            return dataFormat;
        }

        public int getMaxChunkSizeBytes() {
            return maxChunkSizeBytes;
        }

        public int getmaxInFlightRequests() {
            return maxInFlightRequests;
        }
    }

    private final DataFormat dataFormat;
    private final long serverTimeoutMillis;
    private final long clientTimeoutMillis;
    private final String route;
    private final int maxChunkSizeBytes;
    private final int maxInFlightRequests;
    private final long localQueueTimeOut;
    private final String priority;
    private final boolean denyIfBusyV3;
    private final long maxSleepTimeMs;
    private final boolean silentUpgrade;


    private FeedParams(DataFormat dataFormat, long serverTimeout, long clientTimeout, String route,
                       int maxChunkSizeBytes, final int maxInFlightRequests,
                       long localQueueTimeOut, String priority, boolean denyIfBusyV3, long maxSleepTimeMs,
                       boolean silentUpgrade) {
        this.dataFormat = dataFormat;
        this.serverTimeoutMillis = serverTimeout;
        this.clientTimeoutMillis = clientTimeout;
        this.route = route;
        this.maxChunkSizeBytes = maxChunkSizeBytes;
        this.maxInFlightRequests =  maxInFlightRequests;
        this.localQueueTimeOut = localQueueTimeOut;
        this.priority = priority;
        this.denyIfBusyV3 = denyIfBusyV3;
        this.maxSleepTimeMs = maxSleepTimeMs;
        this.silentUpgrade = silentUpgrade;
    }

    public DataFormat getDataFormat() {
        return dataFormat;
    }

    public String getRoute() {
        return route;
    }

    public long getServerTimeout(TimeUnit unit) {
        return unit.convert(serverTimeoutMillis, TimeUnit.MILLISECONDS);
    }

    public long getClientTimeout(TimeUnit unit) {
        return unit.convert(clientTimeoutMillis, TimeUnit.MILLISECONDS);
    }

    public int getMaxChunkSizeBytes() {
        return maxChunkSizeBytes;
    }

    public String getPriority() {
        return priority;
    }

    public String toUriParameters() {
        StringBuilder b = new StringBuilder();
        b.append("&dataformat=").append(dataFormat.name());  //name in dataFormat enum obviously must be ascii
        return b.toString();
    }

    public int getMaxInFlightRequests() {
        return maxInFlightRequests;
    }

    public long getLocalQueueTimeOut() {
        return localQueueTimeOut;
    }

}