Skip to content

Commit

Permalink
Merge pull request #196 from apivideo/feature/android_workmanager_cancel
Browse files Browse the repository at this point in the history
feat(java): improve cancellation of WorkManager uploads
  • Loading branch information
ThibaultBee authored Aug 21, 2023
2 parents 92091f2 + 7562e4b commit ab209bc
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 83 deletions.
2 changes: 2 additions & 0 deletions config/android-uploader.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
changelog:
- 1.3.0 (2023-08-21):
- Improve cancel of upload workers for the WorkManager API
- 1.2.4 (2023-08-10):
- Fix upload with upload token and video id when video is smaller than chunk size
- 1.2.3 (2023-08-08):
Expand Down
2 changes: 2 additions & 0 deletions config/android.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
changelog:
- 1.5.0 (2023-08-21):
- Improve cancel of upload workers for the WorkManager API
- 1.4.2 (2023-08-10):
- Fix upload with upload token and video id when video is smaller than chunk size
- 1.4.1 (2023-08-08):
Expand Down
155 changes: 88 additions & 67 deletions templates/java/android/work/UploadWorkerHelper.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -209,78 +209,16 @@ object UploadWorkerHelper {
file
)
)
.addTag("{{artifactId}}")
.addTag(getTagForUpload(videoId, token))
.addTag(ARTIFACT_ID)
.apply {
videoId?.let { addTag(getTagForVideoId(it)) }
token?.let { addTag(getTagForUploadToken(it)) }
tags.forEach { addTag(it) }
}
.build()
return OperationWithRequest(workManager.enqueue(workRequest), workRequest)
}

/**
* Cancels all works related to a video id that was added with [upload].
* Works with upload token are not cancelled.
*
* @param context The application context
* @param videoId The video id
*/
@JvmStatic
fun cancel(context: Context, videoId: String) =
cancel(WorkManager.getInstance(context), videoId)

/**
* Cancels all works related to a video id that was added with [upload].
* Works with upload token are not cancelled.
*
* @param workManager The WorkManager instance
* @param videoId The video id
*/
@JvmStatic
fun cancel(workManager: WorkManager, videoId: String) =
workManager.cancelAllWorkByTag(getTagForUpload(videoId, null))

/**
* Cancels all works related to an upload token and possibly a video id that was added with [uploadWithUploadToken].
* Works without upload token are not cancelled.
*
* @param context The application context
* @param token The upload token
* @param videoId The video id.Must be the same as the one used in [uploadWithUploadToken].
*/
@JvmStatic
fun cancelWithUploadToken(context: Context, token: String, videoId: String? = null) =
cancelWithUploadToken(WorkManager.getInstance(context), token, videoId)

/**
* Cancels all works related to an upload token and possibly a video id that was added with [uploadWithUploadToken].
* Works without upload token are not cancelled.
*
* @param workManager The WorkManager instance
* @param token The upload token
* @param videoId The video id. Must be the same as the one used in [uploadWithUploadToken].
*/
@JvmStatic
fun cancelWithUploadToken(workManager: WorkManager, token: String, videoId: String? = null) =
workManager.cancelAllWorkByTag(getTagForUpload(videoId, token))

private const val PREFIX_VIDEO_ID = "videoId="
private const val PREFIX_TOKEN = "token="

/**
* Returns the tag used to identify works related to a video id or an upload token.
*
* @param videoId The video id
* @param token The upload token
* @return The tag
*/
fun getTagForUpload(videoId: String?, token: String?): String {
require((token != null) || (videoId != null)) {
"You must provide either a token or a videoId"
}
return "($PREFIX_VIDEO_ID$videoId, $PREFIX_TOKEN$token)"
}

/**
* Enqueues a work to upload a part of a file.
*
Expand Down Expand Up @@ -404,13 +342,96 @@ object UploadWorkerHelper {
partId
)
)
.addTag("{{artifactId}}")
.addTag(ARTIFACT_ID)
.addTag("progressive")
.addTag(getTagForUpload(session.videoId, session.token))
.apply {
session.videoId?.let { addTag(getTagForVideoId(it)) }
session.token?.let { addTag(getTagForUploadToken(it)) }
tags.forEach { addTag(it) }
}
.build()
return OperationWithRequest(workManager.enqueue(workRequest), workRequest)
}

/**
* Cancels all upload works.
*
* @param context The application context
*/
@JvmStatic
fun cancelAll(context: Context) =
cancelAll(WorkManager.getInstance(context))

/**
* Cancels all upload works.
*
* @param workManager The WorkManager instance
*/
@JvmStatic
fun cancelAll(workManager: WorkManager) =
workManager.cancelAllWorkByTag(ARTIFACT_ID)

/**
* Cancels all works related to a video id.
*
* @param context The application context
* @param videoId The video id
*/
@JvmStatic
fun cancel(context: Context, videoId: String) =
cancel(WorkManager.getInstance(context), videoId)

/**
* Cancels all works related to a video id.
*
* @param workManager The WorkManager instance
* @param videoId The video id
*/
@JvmStatic
fun cancel(workManager: WorkManager, videoId: String) =
workManager.cancelAllWorkByTag(getTagForVideoId(videoId))

/**
* Cancels all works related to an upload token that was added with [uploadWithUploadToken].
*
* @param context The application context
* @param token The upload token
*/
@JvmStatic
fun cancelWithUploadToken(context: Context, token: String) =
cancelWithUploadToken(WorkManager.getInstance(context), token)

/**
* Cancels all works related to an upload token that was added with [uploadWithUploadToken].
*
* @param workManager The WorkManager instance
* @param token The upload token
*/
@JvmStatic
fun cancelWithUploadToken(workManager: WorkManager, token: String) =
workManager.cancelAllWorkByTag(getTagForUploadToken(token))

/**
* Returns the tag used to identify works related to a video id.
*
* @param videoId The video id
* @return The tag
*/
fun getTagForVideoId(videoId: String): String {
return "($PREFIX_VIDEO_ID$videoId)"
}

/**
* Returns the tag used to identify works related to an upload token.
*
* @param token The upload token
* @return The tag
*/
fun getTagForUploadToken(token: String): String {
return "($PREFIX_TOKEN$token)"
}

private const val PREFIX_VIDEO_ID = "videoId="
private const val PREFIX_TOKEN = "token="
private const val ARTIFACT_ID = "{{artifactId}}"
}
36 changes: 20 additions & 16 deletions templates/java/android/work/WorkManagerExtensions.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,6 @@ fun WorkManager.uploadWithUploadToken(
workerClass
)

/**
* Extension functions for [WorkManager] to cancel upload works that was added with [WorkManager.upload].
*
* @param videoId The video id
*/
fun WorkManager.cancel(videoId: String) = UploadWorkerHelper.cancel(this, videoId)

/**
* Extension functions for [WorkManager] to cancel upload works that was added with [WorkManager.uploadWithUploadToken].
*
* @param token The upload token
* @param videoId The video id. Must be the same as the one used in [WorkManager.uploadWithUploadToken].
*/
fun WorkManager.cancelWithUploadToken(token: String, videoId: String? = null) =
UploadWorkerHelper.cancelWithUploadToken(this, token, videoId)

/**
* Extension functions for [WorkManager] to enqueue upload works for progressive upload.
*
Expand Down Expand Up @@ -147,3 +131,23 @@ fun WorkManager.uploadPart(
tags,
workerClass
)

/**
* Extension functions for [WorkManager] to cancel all upload works.
*/
fun WorkManager.cancelAllUploads() = UploadWorkerHelper.cancelAll(this)

/**
* Extension functions for [WorkManager] to cancel upload works that was added with [WorkManager.upload].
*
* @param videoId The video id
*/
fun WorkManager.cancel(videoId: String) = UploadWorkerHelper.cancel(this, videoId)

/**
* Extension functions for [WorkManager] to cancel upload works that was added with [WorkManager.uploadWithUploadToken].
*
* @param token The upload token
*/
fun WorkManager.cancelWithUploadToken(token: String) =
UploadWorkerHelper.cancelWithUploadToken(this, token)

0 comments on commit ab209bc

Please sign in to comment.