11
11
import datadog .trace .api .Trace ;
12
12
import io .airbyte .api .client .generated .ConnectionApi ;
13
13
import io .airbyte .api .client .invoker .generated .ApiException ;
14
+ import io .airbyte .api .client .model .generated .ConnectionIdRequestBody ;
14
15
import io .airbyte .api .client .model .generated .ConnectionRead ;
16
+ import io .airbyte .api .client .model .generated .ConnectionSchedule ;
17
+ import io .airbyte .api .client .model .generated .ConnectionScheduleDataBasicSchedule ;
18
+ import io .airbyte .api .client .model .generated .ConnectionScheduleDataBasicSchedule .TimeUnitEnum ;
19
+ import io .airbyte .api .client .model .generated .ConnectionScheduleDataCron ;
20
+ import io .airbyte .api .client .model .generated .ConnectionScheduleType ;
15
21
import io .airbyte .api .client .model .generated .ConnectionStatus ;
16
22
import io .airbyte .commons .temporal .config .WorkerMode ;
17
23
import io .airbyte .commons .temporal .exception .RetryableException ;
18
- import io .airbyte .config .Cron ;
19
24
import io .airbyte .config .StandardSync ;
20
- import io .airbyte .config .StandardSync .ScheduleType ;
21
- import io .airbyte .config .StandardSync .Status ;
22
- import io .airbyte .config .helpers .ScheduleHelpers ;
23
25
import io .airbyte .config .persistence .ConfigNotFoundException ;
24
26
import io .airbyte .config .persistence .ConfigRepository ;
25
27
import io .airbyte .metrics .lib .ApmTraceUtils ;
41
43
import java .util .Set ;
42
44
import java .util .TimeZone ;
43
45
import java .util .UUID ;
46
+ import java .util .concurrent .TimeUnit ;
44
47
import java .util .function .Supplier ;
45
48
import lombok .extern .slf4j .Slf4j ;
46
49
import org .joda .time .DateTimeZone ;
@@ -106,48 +109,48 @@ public StandardSync getStandardSync(final UUID connectionId) throws JsonValidati
106
109
public ScheduleRetrieverOutput getTimeToWait (final ScheduleRetrieverInput input ) {
107
110
try {
108
111
ApmTraceUtils .addTagsToTrace (Map .of (CONNECTION_ID_KEY , input .getConnectionId ()));
109
- final StandardSync standardSync = configRepository . getStandardSync (input .getConnectionId ());
110
-
111
- if (standardSync .getScheduleType () != null ) {
112
- return this .getTimeToWaitFromScheduleType (standardSync , input .getConnectionId ());
112
+ final ConnectionIdRequestBody connectionIdRequestBody = new ConnectionIdRequestBody (). connectionId (input .getConnectionId ());
113
+ final ConnectionRead connectionRead = connectionApi . getConnection ( connectionIdRequestBody );
114
+ if (connectionRead .getScheduleType () != null ) {
115
+ return this .getTimeToWaitFromScheduleType (connectionRead , input .getConnectionId ());
113
116
}
114
- return this .getTimeToWaitFromLegacy (standardSync , input .getConnectionId ());
115
- } catch (final IOException | JsonValidationException | ConfigNotFoundException e ) {
117
+ return this .getTimeToWaitFromLegacy (connectionRead , input .getConnectionId ());
118
+ } catch (final IOException | ApiException e ) {
116
119
throw new RetryableException (e );
117
120
}
118
121
}
119
122
120
123
/**
121
- * @param standardSync
124
+ * @param connectionRead
122
125
* @param connectionId
123
126
* @return
124
127
* @throws IOException
125
128
*
126
129
* This method consumes the `scheduleType` and `scheduleData` fields.
127
130
*/
128
- private ScheduleRetrieverOutput getTimeToWaitFromScheduleType (final StandardSync standardSync , final UUID connectionId ) throws IOException {
129
- if (standardSync .getScheduleType () == ScheduleType .MANUAL || standardSync .getStatus () != Status .ACTIVE ) {
131
+ private ScheduleRetrieverOutput getTimeToWaitFromScheduleType (final ConnectionRead connectionRead , final UUID connectionId ) throws IOException {
132
+ if (connectionRead .getScheduleType () == ConnectionScheduleType .MANUAL || connectionRead .getStatus () != ConnectionStatus .ACTIVE ) {
130
133
// Manual syncs wait for their first run
131
134
return new ScheduleRetrieverOutput (Duration .ofDays (100 * 365 ));
132
135
}
133
136
134
137
final Optional <Job > previousJobOptional = jobPersistence .getLastReplicationJob (connectionId );
135
138
136
- if (standardSync .getScheduleType () == ScheduleType . BASIC_SCHEDULE ) {
139
+ if (connectionRead .getScheduleType () == ConnectionScheduleType . BASIC ) {
137
140
if (previousJobOptional .isEmpty ()) {
138
141
// Basic schedules don't wait for their first run.
139
142
return new ScheduleRetrieverOutput (Duration .ZERO );
140
143
}
141
144
final Job previousJob = previousJobOptional .get ();
142
145
final long prevRunStart = previousJob .getStartedAtInSecond ().orElse (previousJob .getCreatedAtInSecond ());
143
- final long nextRunStart = prevRunStart + ScheduleHelpers . getIntervalInSecond (standardSync .getScheduleData ().getBasicSchedule ());
146
+ final long nextRunStart = prevRunStart + getIntervalInSecond (connectionRead .getScheduleData ().getBasicSchedule ());
144
147
final Duration timeToWait = Duration .ofSeconds (
145
148
Math .max (0 , nextRunStart - currentSecondsSupplier .get ()));
146
149
return new ScheduleRetrieverOutput (timeToWait );
147
150
}
148
151
149
- else { // standardSync .getScheduleType() == ScheduleType .CRON
150
- final Cron scheduleCron = standardSync .getScheduleData ().getCron ();
152
+ else { // connectionRead .getScheduleType() == ConnectionScheduleType .CRON
153
+ final ConnectionScheduleDataCron scheduleCron = connectionRead .getScheduleData ().getCron ();
151
154
final TimeZone timeZone = DateTimeZone .forID (scheduleCron .getCronTimeZone ()).toTimeZone ();
152
155
try {
153
156
final CronExpression cronExpression = new CronExpression (scheduleCron .getCronExpression ());
@@ -164,18 +167,18 @@ private ScheduleRetrieverOutput getTimeToWaitFromScheduleType(final StandardSync
164
167
Duration timeToWait = Duration .ofSeconds (
165
168
Math .max (0 , nextRunStart .getTime () / MS_PER_SECOND - currentSecondsSupplier .get ()));
166
169
167
- timeToWait = addSchedulingNoiseForAllowListedWorkspace (timeToWait , standardSync );
170
+ timeToWait = addSchedulingNoiseForAllowListedWorkspace (timeToWait , connectionRead );
168
171
return new ScheduleRetrieverOutput (timeToWait );
169
172
} catch (final ParseException e ) {
170
173
throw (DateTimeException ) new DateTimeException (e .getMessage ()).initCause (e );
171
174
}
172
175
}
173
176
}
174
177
175
- private Duration addSchedulingNoiseForAllowListedWorkspace (Duration timeToWait , StandardSync standardSync ) {
178
+ private Duration addSchedulingNoiseForAllowListedWorkspace (Duration timeToWait , ConnectionRead connectionRead ) {
176
179
final UUID workspaceId ;
177
180
try {
178
- workspaceId = workspaceHelper .getWorkspaceForConnectionId (standardSync .getConnectionId ());
181
+ workspaceId = workspaceHelper .getWorkspaceForConnectionId (connectionRead .getConnectionId ());
179
182
} catch (JsonValidationException | ConfigNotFoundException e ) {
180
183
// We tolerate exceptions and fail open by doing nothing.
181
184
return timeToWait ;
@@ -184,7 +187,7 @@ private Duration addSchedulingNoiseForAllowListedWorkspace(Duration timeToWait,
184
187
// Only apply to a specific set of workspaces.
185
188
return timeToWait ;
186
189
}
187
- if (!standardSync .getScheduleType ().equals (ScheduleType .CRON )) {
190
+ if (!connectionRead .getScheduleType ().equals (ConnectionScheduleType .CRON )) {
188
191
// Only apply noise to cron connections.
189
192
return timeToWait ;
190
193
}
@@ -197,30 +200,30 @@ private Duration addSchedulingNoiseForAllowListedWorkspace(Duration timeToWait,
197
200
}
198
201
199
202
/**
200
- * @param standardSync
203
+ * @param connectionRead
201
204
* @param connectionId
202
205
* @return
203
206
* @throws IOException
204
207
*
205
208
* This method consumes the `schedule` field.
206
209
*/
207
- private ScheduleRetrieverOutput getTimeToWaitFromLegacy (final StandardSync standardSync , final UUID connectionId ) throws IOException {
208
- if (standardSync .getSchedule () == null || standardSync .getStatus () != Status .ACTIVE ) {
210
+ private ScheduleRetrieverOutput getTimeToWaitFromLegacy (final ConnectionRead connectionRead , final UUID connectionId ) throws IOException {
211
+ if (connectionRead .getSchedule () == null || connectionRead .getStatus () != ConnectionStatus .ACTIVE ) {
209
212
// Manual syncs wait for their first run
210
213
return new ScheduleRetrieverOutput (Duration .ofDays (100 * 365 ));
211
214
}
212
215
213
216
final Optional <Job > previousJobOptional = jobPersistence .getLastReplicationJob (connectionId );
214
217
215
- if (previousJobOptional .isEmpty () && standardSync .getSchedule () != null ) {
218
+ if (previousJobOptional .isEmpty () && connectionRead .getSchedule () != null ) {
216
219
// Non-manual syncs don't wait for their first run
217
220
return new ScheduleRetrieverOutput (Duration .ZERO );
218
221
}
219
222
220
223
final Job previousJob = previousJobOptional .get ();
221
224
final long prevRunStart = previousJob .getStartedAtInSecond ().orElse (previousJob .getCreatedAtInSecond ());
222
225
223
- final long nextRunStart = prevRunStart + ScheduleHelpers . getIntervalInSecond (standardSync .getSchedule ());
226
+ final long nextRunStart = prevRunStart + getIntervalInSecond (connectionRead .getSchedule ());
224
227
225
228
final Duration timeToWait = Duration .ofSeconds (
226
229
Math .max (0 , nextRunStart - currentSecondsSupplier .get ()));
@@ -261,4 +264,46 @@ public Optional<ConnectionStatus> getStatus(final UUID connectionId) {
261
264
}
262
265
}
263
266
267
+ private Long getIntervalInSecond (final ConnectionScheduleDataBasicSchedule schedule ) {
268
+ return getSecondsInUnit (schedule .getTimeUnit ()) * schedule .getUnits ();
269
+ }
270
+
271
+ private Long getIntervalInSecond (final ConnectionSchedule schedule ) {
272
+ return getSecondsInUnit (schedule .getTimeUnit ()) * schedule .getUnits ();
273
+ }
274
+
275
+ private Long getSecondsInUnit (final TimeUnitEnum timeUnitEnum ) {
276
+ switch (timeUnitEnum ) {
277
+ case MINUTES :
278
+ return TimeUnit .MINUTES .toSeconds (1 );
279
+ case HOURS :
280
+ return TimeUnit .HOURS .toSeconds (1 );
281
+ case DAYS :
282
+ return TimeUnit .DAYS .toSeconds (1 );
283
+ case WEEKS :
284
+ return TimeUnit .DAYS .toSeconds (1 ) * 7 ;
285
+ case MONTHS :
286
+ return TimeUnit .DAYS .toSeconds (1 ) * 30 ;
287
+ default :
288
+ throw new RuntimeException ("Unhandled TimeUnitEnum: " + timeUnitEnum );
289
+ }
290
+ }
291
+
292
+ private Long getSecondsInUnit (final ConnectionSchedule .TimeUnitEnum timeUnitEnum ) {
293
+ switch (timeUnitEnum ) {
294
+ case MINUTES :
295
+ return TimeUnit .MINUTES .toSeconds (1 );
296
+ case HOURS :
297
+ return TimeUnit .HOURS .toSeconds (1 );
298
+ case DAYS :
299
+ return TimeUnit .DAYS .toSeconds (1 );
300
+ case WEEKS :
301
+ return TimeUnit .DAYS .toSeconds (1 ) * 7 ;
302
+ case MONTHS :
303
+ return TimeUnit .DAYS .toSeconds (1 ) * 30 ;
304
+ default :
305
+ throw new RuntimeException ("Unhandled TimeUnitEnum: " + timeUnitEnum );
306
+ }
307
+ }
308
+
264
309
}
0 commit comments