2424import org .apache .amoro .ServerTableIdentifier ;
2525import org .apache .amoro .TableRuntime ;
2626import org .apache .amoro .config .TableConfiguration ;
27+ import org .apache .amoro .exception .PersistenceException ;
28+ import org .apache .amoro .process .ProcessStatus ;
2729import org .apache .amoro .server .optimizing .OptimizingStatus ;
30+ import org .apache .amoro .server .persistence .PersistentBase ;
31+ import org .apache .amoro .server .persistence .mapper .TableProcessMapper ;
32+ import org .apache .amoro .server .process .TableProcessMeta ;
2833import org .apache .amoro .server .table .DefaultTableRuntime ;
2934import org .apache .amoro .server .table .RuntimeHandlerChain ;
3035import org .apache .amoro .server .table .TableService ;
3136import org .apache .amoro .server .table .cleanup .CleanupOperation ;
37+ import org .apache .amoro .server .utils .SnowflakeIdGenerator ;
38+ import org .apache .amoro .shade .guava32 .com .google .common .annotations .VisibleForTesting ;
3239import org .apache .amoro .shade .guava32 .com .google .common .util .concurrent .ThreadFactoryBuilder ;
3340import org .apache .commons .lang3 .StringUtils ;
3441import org .slf4j .Logger ;
3542import org .slf4j .LoggerFactory ;
3643
3744import java .util .Collections ;
45+ import java .util .HashMap ;
3846import java .util .HashSet ;
3947import java .util .List ;
4048import java .util .Locale ;
@@ -48,6 +56,12 @@ public abstract class PeriodicTableScheduler extends RuntimeHandlerChain {
4856 protected final Logger logger = LoggerFactory .getLogger (getClass ());
4957
5058 private static final long START_DELAY = 10 * 1000L ;
59+ private static final String CLEANUP_EXECUTION_ENGINE = "AMORO" ;
60+ private static final String CLEANUP_PROCESS_STAGE = "CLEANUP" ;
61+ private static final String EXTERNAL_PROCESS_IDENTIFIER = "" ;
62+ private static final SnowflakeIdGenerator ID_GENERATOR = new SnowflakeIdGenerator ();
63+
64+ private final PersistenceHelper persistenceHelper = new PersistenceHelper ();
5165
5266 protected final Set <ServerTableIdentifier > scheduledTables =
5367 Collections .synchronizedSet (new HashSet <>());
@@ -123,16 +137,31 @@ private void scheduleTableExecution(TableRuntime tableRuntime, long delay) {
123137 }
124138
125139 private void executeTask (TableRuntime tableRuntime ) {
140+ TableProcessMeta cleanupProcessMeta = null ;
141+ CleanupOperation cleanupOperation = null ;
142+ Exception executionError = null ;
143+ long cleanupEndTime = 0L ;
144+
126145 try {
127146 if (isExecutable (tableRuntime )) {
147+ cleanupOperation = getCleanupOperation ();
148+ // create and persist cleanup process info
149+ cleanupProcessMeta = createCleanupProcessInfo (tableRuntime , cleanupOperation );
150+
128151 execute (tableRuntime );
152+
129153 // Different tables take different amounts of time to execute the end of execute(),
130154 // so you need to perform the update operation separately for each table.
131- persistUpdatingCleanupTime (tableRuntime );
155+ cleanupEndTime = System .currentTimeMillis ();
156+ persistUpdatingCleanupTime (tableRuntime , cleanupEndTime );
132157 }
133158 } catch (Exception e ) {
134159 logger .error ("exception when schedule for table: {}" , tableRuntime .getTableIdentifier (), e );
160+ executionError = e ;
135161 } finally {
162+ // persist cleanup result info.
163+ persistCleanupResult (
164+ tableRuntime , cleanupOperation , cleanupProcessMeta , cleanupEndTime , executionError );
136165 scheduledTables .remove (tableRuntime .getTableIdentifier ());
137166 scheduleIfNecessary (tableRuntime , getNextExecutingTime (tableRuntime ));
138167 }
@@ -156,14 +185,13 @@ protected boolean shouldExecute(Long lastCleanupEndTime) {
156185 return true ;
157186 }
158187
159- private void persistUpdatingCleanupTime (TableRuntime tableRuntime ) {
188+ private void persistUpdatingCleanupTime (TableRuntime tableRuntime , long currentTime ) {
160189 CleanupOperation cleanupOperation = getCleanupOperation ();
161190 if (shouldSkipOperation (tableRuntime , cleanupOperation )) {
162191 return ;
163192 }
164193
165194 try {
166- long currentTime = System .currentTimeMillis ();
167195 ((DefaultTableRuntime ) tableRuntime ).updateLastCleanTime (cleanupOperation , currentTime );
168196
169197 logger .debug (
@@ -178,6 +206,125 @@ private void persistUpdatingCleanupTime(TableRuntime tableRuntime) {
178206 }
179207 }
180208
209+ @ VisibleForTesting
210+ public TableProcessMeta createCleanupProcessInfo (
211+ TableRuntime tableRuntime , CleanupOperation cleanupOperation ) {
212+ if (shouldSkipOperation (tableRuntime , cleanupOperation )) {
213+ return null ;
214+ }
215+
216+ TableProcessMeta cleanupProcessMeta = buildCleanupProcessMeta (tableRuntime , cleanupOperation );
217+ persistenceHelper .beginAndPersistCleanupProcess (cleanupProcessMeta );
218+ logger .debug (
219+ "Successfully persist cleanup process [processId={}, tableId={}, processType={}]" ,
220+ cleanupProcessMeta .getProcessId (),
221+ cleanupProcessMeta .getTableId (),
222+ cleanupProcessMeta .getProcessType ());
223+
224+ return cleanupProcessMeta ;
225+ }
226+
227+ private TableProcessMeta buildCleanupProcessMeta (
228+ TableRuntime tableRuntime , CleanupOperation cleanupOperation ) {
229+ TableProcessMeta cleanupProcessMeta = new TableProcessMeta ();
230+
231+ cleanupProcessMeta .setTableId (tableRuntime .getTableIdentifier ().getId ());
232+ cleanupProcessMeta .setProcessId (ID_GENERATOR .generateId ());
233+ cleanupProcessMeta .setExternalProcessIdentifier (EXTERNAL_PROCESS_IDENTIFIER );
234+ cleanupProcessMeta .setStatus (ProcessStatus .RUNNING );
235+ cleanupProcessMeta .setProcessType (cleanupOperation .name ());
236+ cleanupProcessMeta .setProcessStage (CLEANUP_PROCESS_STAGE );
237+ cleanupProcessMeta .setExecutionEngine (CLEANUP_EXECUTION_ENGINE );
238+ cleanupProcessMeta .setRetryNumber (0 );
239+ cleanupProcessMeta .setFinishTime (0 );
240+ cleanupProcessMeta .setFailMessage ("" );
241+ cleanupProcessMeta .setCreateTime (System .currentTimeMillis ());
242+ cleanupProcessMeta .setProcessParameters (new HashMap <>());
243+ cleanupProcessMeta .setSummary (new HashMap <>());
244+
245+ return cleanupProcessMeta ;
246+ }
247+
248+ @ VisibleForTesting
249+ public void persistCleanupResult (
250+ TableRuntime tableRuntime ,
251+ CleanupOperation cleanupOperation ,
252+ TableProcessMeta cleanupProcessMeta ,
253+ long cleanupEndTime ,
254+ Exception executionError ) {
255+
256+ if (cleanupOperation == null
257+ || cleanupProcessMeta == null
258+ || shouldSkipOperation (tableRuntime , cleanupOperation )) {
259+ return ;
260+ }
261+
262+ cleanupProcessMeta .setFinishTime (cleanupEndTime );
263+ if (executionError != null ) {
264+ cleanupProcessMeta .setStatus (ProcessStatus .FAILED );
265+ cleanupProcessMeta .setFailMessage (executionError .getMessage ());
266+ } else {
267+ cleanupProcessMeta .setStatus (ProcessStatus .SUCCESS );
268+ }
269+
270+ try {
271+ persistenceHelper .updateAndPersistCleanupProcess (cleanupProcessMeta );
272+ } catch (PersistenceException e ) {
273+ logger .error (
274+ "Failed to persist cleanup process result [processId={}, tableId={}, processType={}]" ,
275+ cleanupProcessMeta .getProcessId (),
276+ cleanupProcessMeta .getTableId (),
277+ cleanupProcessMeta .getProcessType (),
278+ e );
279+ }
280+
281+ logger .debug (
282+ "Successfully updated lastCleanTime and cleanupProcess for table {} with processId={}, cleanup operation {}" ,
283+ tableRuntime .getTableIdentifier ().getTableName (),
284+ cleanupProcessMeta .getProcessId (),
285+ cleanupOperation );
286+ }
287+
288+ private static class PersistenceHelper extends PersistentBase {
289+
290+ public PersistenceHelper () {}
291+
292+ private void beginAndPersistCleanupProcess (TableProcessMeta meta ) {
293+ doAs (
294+ TableProcessMapper .class ,
295+ mapper ->
296+ mapper .insertProcess (
297+ meta .getTableId (),
298+ meta .getProcessId (),
299+ meta .getExternalProcessIdentifier (),
300+ meta .getStatus (),
301+ meta .getProcessType (),
302+ meta .getProcessStage (),
303+ meta .getExecutionEngine (),
304+ meta .getRetryNumber (),
305+ meta .getCreateTime (),
306+ meta .getProcessParameters (),
307+ meta .getSummary ()));
308+ }
309+
310+ private void updateAndPersistCleanupProcess (TableProcessMeta meta ) {
311+ doAs (
312+ TableProcessMapper .class ,
313+ mapper ->
314+ mapper .updateProcess (
315+ meta .getTableId (),
316+ meta .getProcessId (),
317+ meta .getExternalProcessIdentifier (),
318+ meta .getStatus (),
319+ meta .getProcessStage (),
320+ meta .getRetryNumber (),
321+ meta .getFinishTime (),
322+ meta .getFailMessage (),
323+ meta .getProcessParameters (),
324+ meta .getSummary ()));
325+ }
326+ }
327+
181328 /**
182329 * Get cleanup operation. Default is NONE, subclasses should override this method to provide
183330 * specific operation.
0 commit comments