-
-
Notifications
You must be signed in to change notification settings - Fork 9
Enable cancellation for Lift exports #3664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3664 +/- ##
==========================================
+ Coverage 72.83% 72.85% +0.01%
==========================================
Files 287 287
Lines 10701 10726 +25
Branches 1330 1331 +1
==========================================
+ Hits 7794 7814 +20
- Misses 2512 2517 +5
Partials 395 395
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
</span> | ||
</Tooltip> | ||
<> | ||
<Tooltip title={!exports ? t("projectExport.cannotExportEmpty") : ""}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this tooltip will never be active when the reset button is also active, but it feels odd to have it around the reset button too, especially since we might want to give the reset button its own tooltip.
Backend/Services/LiftService.cs
Outdated
// cancelled | ||
|
||
|
||
// note cancelled | ||
_liftExports.Remove(userId); | ||
_liftExports.Add(userId, filePath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@imnasnainaec the Dictionary class is not thread safe and the more you use it the more likely you are to run into trouble. I would swap it out for Concurrent Dictionary which is thread safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could do that instead, but it would be much simpler to use the correct type. It's also much more reliable as you have to be careful with locks to not access the object outside of the lock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 9 files at r2, 3 of 7 files at r5, all commit messages.
Reviewable status: 5 of 14 files reviewed, 4 unresolved discussions (waiting on @andracc)
Backend/Controllers/LiftController.cs
line 289 at r5 (raw file):
/// <summary> Cancels project export </summary> /// <returns> ProjectId, if cancel successful </returns> [HttpGet("cancelExport", Name = "CancelLiftExport")]
Use all-lowercase urls:"cancelExport"
-> "cancelexport"
Backend/Controllers/LiftController.cs
line 377 at r5 (raw file):
await _notifyService.Clients.All.SendAsync(CombineHub.DownloadReady, userId); } return true;
return proceed;
might make more sense, even if we're not using that return value.
Backend/Services/LiftService.cs
line 155 at r5 (raw file):
{ _liftExports.TryAdd(userId, (InProgress, exportId)); }
I think you could use .AddOrUpdate
(rather than .TryRemove
and .TryAdd
) to avoid a lock in SetExportInProgress
(and possibly elsewhere).
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed all commit messages.
Reviewable status: 5 of 17 files reviewed, 3 unresolved discussions (waiting on @andracc)
Backend/Services/LiftService.cs
line 138 at r6 (raw file):
/// <summary> Store status that a user's export is cancelled. </summary> public void SetCancelExport(string userId)
Since SetCancelExport
isn't setting anything, something like CancelExport
or ClearExportInProgress
would be more accurate.
Backend/Services/LiftService.cs
line 144 at r6 (raw file):
/// <summary> Store status that a user's export is in-progress. </summary> public void SetExportInProgress(string userId, bool isInProgress, string exportId)
Now that we have a function to cancel exports, that can be used instead of this with isInProgress = false
, so we can drop that middle bool
param (and add a check to throw an error if exportId
is empty).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dismissed @hahn-kev from a discussion.
Reviewable status: 5 of 17 files reviewed, 3 unresolved discussions (waiting on @andracc)
src/components/ProjectExport/Redux/ExportProjectReduxTypes.ts
line 2 at r9 (raw file):
export enum ExportStatus { Canceling = "CANCELING",
I'm not sure why/whether we need this added status option for the Redux state or if it's sufficient to handle the canceling
state within the ExportButton
component.
Backend/Services/PermissionService.cs
line 144 at r9 (raw file):
return ""; } return exportId;
Can simplify to return request.TraceIdentifier ?? "";
src/components/ProjectExport/ExportButton.tsx
line 25 at r9 (raw file):
export default function ExportButton(props: ExportButtonProps): ReactElement { const dispatch = useAppDispatch(); const [canceling, setCanceling] = useState(false);
This component state canceling
should only be necessary if we get rid of the ExportStatus.Canceling
in the Redux state. If we keep that, then you should be able to use status === ExportStatus.Canceling
in place of canceling
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 10 files at r7, 4 of 11 files at r10, all commit messages.
Reviewable status: 8 of 17 files reviewed, 4 unresolved discussions (waiting on @andracc)
src/backend/index.ts
line 278 at r10 (raw file):
/** Tell the backend to cancel the LIFT file export. */ // revisit
// revisit
revisited yet?
src/components/ProjectExport/Redux/ExportProjectActions.ts
line 45 at r11 (raw file):
export function asyncCancelExport(projectId: string) { return async () => { await cancelExport(projectId);
After cancelling the export, this needs to dispatch the resetExportAction
src/components/ProjectExport/Redux/ExportProjectActions.ts
line 14 at r10 (raw file):
// Action Creation Functions
Please re-add this removed newline. The comment applies to multiple function, not just the next one .
Backend/Services/LiftService.cs
line 122 at r10 (raw file):
/// A dictionary shared by all Projects for storing and retrieving paths to in-process imports. /// </summary> private readonly Dictionary<string, string> _liftImports;
Let's also make _liftImports
a ConcurrentDictionary
. And then the StoreImport
function below could be
public void StoreImport(string userId, string filePath)
{
_liftImports.AddOrUpdate(userId, filePath, (_, _) => filePath);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 6 files at r9, 1 of 11 files at r10, 1 of 2 files at r11, 2 of 5 files at r12, all commit messages.
Reviewable status: 13 of 18 files reviewed, 1 unresolved discussion (waiting on @andracc)
Backend/Controllers/LiftController.cs
line 294 at r13 (raw file):
{ var userId = _permissionService.GetUserId(HttpContext); return CancelLiftExport(userId);
To get ...ResponseType(StatusCodes.Status200OK...
, this should be
return Ok(CancelLiftExport(userId));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 5 files at r12.
Reviewable status: 14 of 18 files reviewed, 5 unresolved discussions (waiting on @andracc)
src/components/ProjectExport/ExportButton.tsx
line 36 at r13 (raw file):
async function cancelExport(): Promise<void> { setCanceling(true); await dispatch(asyncCancelExport());
Because asyncCancelExport
updates the Redux state before awaiting anything, there's no appreciable delay between setCanceling(true)
and when status
is ExportStatus.Exporting
again. We can getting rid of this component's canceling
state and not even worry about disabling the export button after it's clicked.
Just in case of future changes that would give time for a second click, I artificially added a delay to the cancel function so I could click the button multiple times, and that didn't cause any error.
src/components/ProjectExport/ExportButton.tsx
line 44 at r13 (raw file):
useEffect(() => { console.log("status: ", status);
Don't forget to remove this console.log
when you're done with it.
src/components/ProjectExport/ExportButton.tsx
line 78 at r13 (raw file):
</span> </Tooltip> {status == ExportStatus.Exporting && (
This should be ===
src/components/ProjectExport/ExportButton.tsx
line 79 at r13 (raw file):
</Tooltip> {status == ExportStatus.Exporting && ( <Tooltip title="Cancel export">
This tooltip text needs to be localized, something like projectExport.cancelExport
with the associated entry added to public/locales/en/translation.json
Also, it'd be good to use our IconButtonWithTooltip
for this cancel button to help us maintain uniform button styling:
{status == ExportStatus.Exporting && (
<IconButtonWithTooltip
disabled={canceling}
icon={<Cancel />}
onClick={cancelExport}
textId={"projectExport.cancelExport"}
/>
)}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 14 of 18 files reviewed, 5 unresolved discussions (waiting on @andracc)
Backend/Controllers/LiftController.cs
line 294 at r13 (raw file):
Previously, imnasnainaec (D. Ror.) wrote…
To get
...ResponseType(StatusCodes.Status200OK...
, this should be
return Ok(CancelLiftExport(userId));
Rather, it can return Ok(_liftService.CancelRecentExport(userId));
and you can delete private bool CancelLiftExport(string userId)
, since that's not used elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 5 files at r12, 5 of 5 files at r14, all commit messages.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on @andracc)
Resolves #3254
This change is