CE-938 More flexible check in (can update message and control expires-timestamp)

This commit is contained in:
2024-05-24 16:59:56 -05:00
parent a6e0741175
commit 66b2b4ff4c
2 changed files with 225 additions and 14 deletions

View File

@ -233,10 +233,68 @@ public class ProcessLockUtils
/*******************************************************************************
** input wrapper for an overload of the checkin method, to allow more flexibility
** w/ whether or not you want to update details & expiresAtTimestamp (e.g., so a
** null can be passed in, to mean "set it to null" vs. "don't update it").
*******************************************************************************/
public static class CheckInInput
{
private ProcessLock processLock;
private Instant expiresAtTimestamp = null;
private boolean wasGivenExpiresAtTimestamp = false;
private String details = null;
private boolean wasGivenDetails = false;
/*******************************************************************************
** Constructor
**
*******************************************************************************/
public static void checkIn(ProcessLock processLock)
public CheckInInput(ProcessLock processLock)
{
this.processLock = processLock;
}
/*******************************************************************************
**
*******************************************************************************/
public CheckInInput withExpiresAtTimestamp(Instant expiresAtTimestamp)
{
this.expiresAtTimestamp = expiresAtTimestamp;
this.wasGivenExpiresAtTimestamp = true;
return (this);
}
/*******************************************************************************
**
*******************************************************************************/
public CheckInInput withDetails(String details)
{
this.details = details;
this.wasGivenDetails = true;
return (this);
}
}
/*******************************************************************************
** Do a check-in, with a specific value for the expiresAtTimestamp - which can
** be set to null to make it null in the lock.
**
** If you don't want to specify the expiresAtTimestamp, call the overload that
** doesn't take the timestamp - in which case it'll either stay the same as it
** was, or will be set based on the type's default.
*******************************************************************************/
public static void checkIn(CheckInInput input)
{
ProcessLock processLock = input.processLock;
try
{
if(processLock == null)
@ -245,25 +303,44 @@ public class ProcessLockUtils
return;
}
ProcessLockType lockType = getProcessLockTypeById(processLock.getProcessLockTypeId());
if(lockType == null)
{
throw (new QException("Unrecognized process lock type id: " + processLock.getProcessLockTypeId()));
}
Instant now = Instant.now();
QRecord recordToUpdate = new QRecord()
.withValue("id", processLock.getId())
.withValue("checkInTimestamp", now);
.withValue("checkInTimestamp", Instant.now());
///////////////////////////////////////////////////////////////////
// if the input was given a details string, update the details //
// use boolean instead of null to know whether or not to do this //
///////////////////////////////////////////////////////////////////
if(input.wasGivenDetails)
{
recordToUpdate.setValue("details", input.details);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// if the input object had an expires-at timestamp put in it, then use that value (null or otherwise) for the expires-at-timestamp //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(input.wasGivenExpiresAtTimestamp)
{
recordToUpdate.setValue("expiresAtTimestamp", input.expiresAtTimestamp);
}
else
{
////////////////////////////////////////////////////////////////////////////////
// else, do the default thing - which is, look for a default in the lock type //
////////////////////////////////////////////////////////////////////////////////
ProcessLockType lockType = getProcessLockTypeById(processLock.getProcessLockTypeId());
if(lockType != null)
{
Integer defaultExpirationSeconds = lockType.getDefaultExpirationSeconds();
if(defaultExpirationSeconds != null)
{
recordToUpdate.setValue("expiresAtTimestamp", now.plusSeconds(defaultExpirationSeconds));
recordToUpdate.setValue("expiresAtTimestamp", Instant.now().plusSeconds(defaultExpirationSeconds));
}
}
}
new UpdateAction().execute(new UpdateInput(ProcessLock.TABLE_NAME).withRecord(recordToUpdate));
LOG.debug("Updated processLock checkInTimestamp", logPair("id", processLock.getId()), logPair("checkInTimestamp", now));
LOG.debug("Checked in on process lock", logPair("id", processLock.getId()));
}
catch(Exception e)
{
@ -273,6 +350,33 @@ public class ProcessLockUtils
/*******************************************************************************
** Do a check-in, with a specific value for the expiresAtTimestamp - which can
** be set to null to make it null in the lock.
**
** If you don't want to specify the expiresAtTimestamp, call the overload that
** doesn't take the timestamp - in which case it'll either stay the same as it
** was, or will be set based on the type's default.
*******************************************************************************/
public static void checkIn(ProcessLock processLock, Instant expiresAtTimestamp)
{
checkIn(new CheckInInput(processLock).withExpiresAtTimestamp(expiresAtTimestamp));
}
/*******************************************************************************
** Do a check-in, updating the expires-timestamp based on the lock type's default.
** (or leaving it the same as it was (null or otherwise) if there is no default
** on the type).
*******************************************************************************/
public static void checkIn(ProcessLock processLock)
{
checkIn(new CheckInInput(processLock));
}
/*******************************************************************************
**
*******************************************************************************/

View File

@ -271,4 +271,111 @@ class ProcessLockUtilsTest extends BaseTest
}
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testCheckInExpiresAtTimestampsWithNoDefault() throws QException
{
/////////////////////////////////////////
// this type has no default expiration //
/////////////////////////////////////////
ProcessLock processLock = ProcessLockUtils.create("1", "typeA", null);
assertNull(processLock.getExpiresAtTimestamp());
/////////////////////////////////////////////////////////////
// checkin w/o specifying an expires-time - leaves it null //
/////////////////////////////////////////////////////////////
ProcessLockUtils.checkIn(processLock);
processLock = ProcessLockUtils.getById(processLock.getId());
assertNull(processLock.getExpiresAtTimestamp());
//////////////////////////////////////////////
// checkin specifying null - leaves it null //
//////////////////////////////////////////////
ProcessLockUtils.checkIn(processLock, null);
processLock = ProcessLockUtils.getById(processLock.getId());
assertNull(processLock.getExpiresAtTimestamp());
//////////////////////////////////////////////
// checkin w/ a time - sets it to that time //
//////////////////////////////////////////////
Instant specifiedTime = Instant.now();
ProcessLockUtils.checkIn(processLock, specifiedTime);
processLock = ProcessLockUtils.getById(processLock.getId());
assertEquals(specifiedTime, processLock.getExpiresAtTimestamp());
///////////////////////////////////////////////////////////
// checkin w/o specifying time - leaves it previous time //
///////////////////////////////////////////////////////////
SleepUtils.sleep(1, TimeUnit.MILLISECONDS);
ProcessLockUtils.checkIn(processLock);
processLock = ProcessLockUtils.getById(processLock.getId());
assertEquals(specifiedTime, processLock.getExpiresAtTimestamp());
////////////////////////////////////////////////////
// checkin specifying null - puts it back to null //
////////////////////////////////////////////////////
ProcessLockUtils.checkIn(processLock, null);
processLock = ProcessLockUtils.getById(processLock.getId());
assertNull(processLock.getExpiresAtTimestamp());
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testCheckInExpiresAtTimestampsWithSomeDefault() throws QException
{
/////////////////////////////////////////
// this type has a default expiration //
/////////////////////////////////////////
ProcessLock processLock = ProcessLockUtils.create("1", "typeB", null);
assertNotNull(processLock.getExpiresAtTimestamp());
Instant expiresAtTimestamp = processLock.getExpiresAtTimestamp();
///////////////////////////////////////////////////////////////
// checkin w/o specifying an expires-time - moves it forward //
///////////////////////////////////////////////////////////////
SleepUtils.sleep(1, TimeUnit.MILLISECONDS);
ProcessLockUtils.checkIn(processLock);
processLock = ProcessLockUtils.getById(processLock.getId());
assertNotNull(processLock.getExpiresAtTimestamp());
assertNotEquals(expiresAtTimestamp, processLock.getExpiresAtTimestamp());
///////////////////////////////////////////////
// checkin specifying null - sets it to null //
///////////////////////////////////////////////
ProcessLockUtils.checkIn(processLock, null);
processLock = ProcessLockUtils.getById(processLock.getId());
assertNull(processLock.getExpiresAtTimestamp());
//////////////////////////////////////////////
// checkin w/ a time - sets it to that time //
//////////////////////////////////////////////
Instant specifiedTime = Instant.now();
ProcessLockUtils.checkIn(processLock, specifiedTime);
processLock = ProcessLockUtils.getById(processLock.getId());
assertEquals(specifiedTime, processLock.getExpiresAtTimestamp());
/////////////////////////////////////////////////////////////////////////
// checkin w/o specifying time - uses the default and moves it forward //
/////////////////////////////////////////////////////////////////////////
SleepUtils.sleep(1, TimeUnit.MILLISECONDS);
ProcessLockUtils.checkIn(processLock);
processLock = ProcessLockUtils.getById(processLock.getId());
assertNotEquals(specifiedTime, processLock.getExpiresAtTimestamp());
////////////////////////////////////////////////////
// checkin specifying null - puts it back to null //
////////////////////////////////////////////////////
ProcessLockUtils.checkIn(processLock, null);
processLock = ProcessLockUtils.getById(processLock.getId());
assertNull(processLock.getExpiresAtTimestamp());
}
}