Skip to content

Commit 4cf3a97

Browse files
authored
Merge pull request #452 from dres-dev/dev
V2.0.0-RC2
2 parents f6ef379 + 0d362b1 commit 4cf3a97

10 files changed

Lines changed: 234 additions & 30 deletions

File tree

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ The backend looks for a file named `config.json` at the location from where it i
8484

8585
## First Steps
8686

87-
Using the DRES CLI, the `help` command lists available commands and their usage. If one would like to know more about a certain command, use the argument `-h`.
88-
Following the first steps towards a successful installment of a (distributed) retrieval evaluation campagn. A prerequisit is the previous deployment, see [Setup](#setup) and a running DRES instance.
87+
Using the DRES CLI, the `help` command lists available commands and their usage. If one would like to know more about a certain command `$cmd`, use the argument `-h`: `DRES> $cmd -h`
88+
Following the first steps towards a successful installment of a (distributed) retrieval evaluation campaign. A prerequisit is the previous deployment, see [Setup](#setup) and a running DRES instance.
8989

9090
### Create User
9191

@@ -130,17 +130,18 @@ Then, navigate to _Evaluation Template Builder_ and create a new competition. Fo
130130
### Create Competition Run
131131

132132
An evaluation template serves as the template for one or more _evaluation runs_.
133-
Please keep in mind, that once a _run_ was created, changes on the template are not reflected in the run.
133+
Please keep in mind, that once a _run_ was created, changes on the template are not reflected in that run.
134134

135-
Evaluation runs are created from the _Evaluations_ view, where one uses the "+" button to create a new one.
135+
Evaluation runs are created from the _Evaluation Template Overview_ view, where one uses the "Exit" (a running person) button to create a new one.
136136

137137
In a non distributed setting, it might be desirable, that participants cannot view the actual run from the frontend,
138138
but require an external source for the query hints (e.g. a large monitor). This could be achieved by unchecking the corresponding option in the dialog.
139+
A run must be of either type `SYNCHRONOUS` or `ASYNCHRONOUS`. The former has task presentation and task execution syncrhonised for all participants and the latter enables task execution individually per participant.
139140

140141
### Runnig the evaluation
141142

142143
As evaluation _operator_, one has to first start the run, then switch to a fitting task and ultimately start the task.
143-
Query hints are displayed as configured to all viewers, once they are all loaded (depending on the setup, this might take a breif moment).
144+
Query hints are displayed as configured to all viewers, once they are all loaded (depending on the setup, this might take a brief moment).
144145
Viewers and participants are shown the message "_Waiting for host to start task_". In case this seems to take too long,
145146
the operator can switch to the admin view and force all participants to be ready, by clicking the red ones.
146147

@@ -153,6 +154,9 @@ It is recommended that all programmatic interaction with the DRES server is done
153154

154155
**Notice:** We strongly recommend the usage of the [client OpenApi Specification](doc/oas-client.json) to generate the code to submit (and generally interact with the server)!
155156

157+
**Notice:** With version 2.0.0, we provide a new POST submission endpoint which is more flexible than the legacy GET one.
158+
That is, for version 2.0.0 the legacy submission endpoint remains in the API version 1 and is deprecated. We highly encourage to move to the new POST-based endpoint.
159+
156160
---
157161

158162
For legacy reasons, we provide further information below:

backend/src/main/kotlin/dev/dres/api/cli/EvaluationTemplateCommand.kt

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ class EvaluationTemplateCommand(private val cache: CacheManager) :
5858
/**
5959
* [CliktCommand] to create a new [DbEvaluationTemplate].
6060
*/
61-
inner class Create : CliktCommand(name = "create", help = "Creates a new Template") {
61+
inner class Create : CliktCommand(
62+
name = "create",
63+
help = "Creates a new Template",
64+
printHelpOnEmptyArgs = true
65+
) {
6266

6367
private val name: String by option("-t", "--template", help = "Name of the new Template")
6468
.required()
@@ -77,7 +81,11 @@ class EvaluationTemplateCommand(private val cache: CacheManager) :
7781
/**
7882
* [CliktCommand] to delete a [DbEvaluationTemplate].
7983
*/
80-
inner class Delete : CliktCommand(name = "delete", help = "Deletes a template", printHelpOnEmptyArgs = true) {
84+
inner class Delete : CliktCommand(
85+
name = "delete",
86+
help = "Deletes a template",
87+
printHelpOnEmptyArgs = true
88+
) {
8189

8290
private val id: String by option("-i", "--id").required()
8391
.validate { require(it.isNotEmpty()) { "Id must be non empty." } }
@@ -96,7 +104,11 @@ class EvaluationTemplateCommand(private val cache: CacheManager) :
96104
/**
97105
* [CliktCommand] to copy a [DbEvaluationTemplate].
98106
*/
99-
inner class Copy : CliktCommand(name = "copy", help = "Copies a Template", printHelpOnEmptyArgs = true) {
107+
inner class Copy : CliktCommand(
108+
name = "copy",
109+
help = "Copies a Template",
110+
printHelpOnEmptyArgs = true
111+
) {
100112

101113
private val id: String by option("-i", "--id").required()
102114
.validate { require(it.isNotEmpty()) { "Id must be non empty." } }
@@ -116,7 +128,11 @@ class EvaluationTemplateCommand(private val cache: CacheManager) :
116128
/**
117129
* [CliktCommand] to rename a [DbEvaluationTemplate].
118130
*/
119-
inner class Rename : CliktCommand(name = "rename", help = "Renames a Template") {
131+
inner class Rename : CliktCommand(
132+
name = "rename",
133+
help = "Renames a Template",
134+
printHelpOnEmptyArgs = true
135+
) {
120136

121137
private val id: String by option("-i", "--id").required()
122138
.validate { require(it.isNotEmpty()) { "Id must be non empty." } }
@@ -148,6 +164,7 @@ class EvaluationTemplateCommand(private val cache: CacheManager) :
148164
inner class List : CliktCommand(name = "list", help = "Lists an overview of all Templates") {
149165
override fun run() {
150166
var no = 0
167+
println()
151168
println(table {
152169
cellStyle {
153170
border = true
@@ -202,7 +219,8 @@ class EvaluationTemplateCommand(private val cache: CacheManager) :
202219
*/
203220
inner class Prepare : CliktCommand(
204221
name = "prepare",
205-
help = "Checks the used media items and generates precomputed previews."
222+
help = "Checks the used media items and generates precomputed previews.",
223+
printHelpOnEmptyArgs = true
206224
) {
207225

208226
private val id: String by option("-i", "--id").required()
@@ -224,7 +242,11 @@ class EvaluationTemplateCommand(private val cache: CacheManager) :
224242
/**
225243
* Exports a specific evaluation to a JSON file.
226244
*/
227-
inner class Export : CliktCommand(name = "export", help = "Exports a template as JSON.") {
245+
inner class Export : CliktCommand(
246+
name = "export",
247+
help = "Exports a template as JSON.",
248+
printHelpOnEmptyArgs = true
249+
) {
228250

229251
/** Path to the file that should be created .*/
230252
private val path: Path by option("-o", "--out", help = "The destination file for the template.").path()
@@ -266,7 +288,11 @@ class EvaluationTemplateCommand(private val cache: CacheManager) :
266288
/**
267289
* Imports a template from a JSON file.
268290
*/
269-
inner class Import : CliktCommand(name = "import", help = "Imports a template from JSON.") {
291+
inner class Import : CliktCommand(
292+
name = "import",
293+
help = "Imports a template from JSON.",
294+
printHelpOnEmptyArgs = true
295+
) {
270296

271297
/** Path to the file that should be imported.*/
272298
private val path: Path by option("-i", "--in", help = "The file to import the template from.").path().required()
Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package dev.dres.api.rest.handler.evaluation.client
22

33
import dev.dres.api.rest.handler.GetRestHandler
4-
import dev.dres.api.rest.types.evaluation.ApiEvaluationType
5-
import dev.dres.api.rest.types.evaluation.ApiEvaluationInfo
4+
import dev.dres.api.rest.types.evaluation.ApiClientEvaluationInfo
65
import dev.dres.api.rest.types.status.ErrorStatus
76
import dev.dres.data.model.run.DbEvaluation
8-
import dev.dres.run.InteractiveAsynchronousRunManager
9-
import dev.dres.run.InteractiveSynchronousRunManager
107
import io.javalin.http.Context
118
import io.javalin.openapi.*
129

@@ -18,7 +15,7 @@ import io.javalin.openapi.*
1815
* @author Loris Sauter
1916
* @version 2.0.0
2017
*/
21-
class ClientListEvaluationsHandler : AbstractEvaluationClientHandler(), GetRestHandler<List<ApiEvaluationInfo>> {
18+
class ClientListEvaluationsHandler : AbstractEvaluationClientHandler(), GetRestHandler<List<ApiClientEvaluationInfo>> {
2219

2320
override val route = "client/evaluation/list"
2421

@@ -28,17 +25,17 @@ class ClientListEvaluationsHandler : AbstractEvaluationClientHandler(), GetRestH
2825
operationId = OpenApiOperation.AUTO_GENERATE,
2926
tags = ["Evaluation Client"],
3027
responses = [
31-
OpenApiResponse("200", [OpenApiContent(Array<ApiEvaluationInfo>::class)]),
28+
OpenApiResponse("200", [OpenApiContent(Array<ApiClientEvaluationInfo>::class)]),
3229
OpenApiResponse("401", [OpenApiContent(ErrorStatus::class)])
3330
],
3431
queryParams = [
3532
OpenApiParam("session", String::class, "Session Token")
3633
],
3734
methods = [HttpMethod.GET]
3835
)
39-
override fun doGet(ctx: Context): List<ApiEvaluationInfo> {
36+
override fun doGet(ctx: Context): List<ApiClientEvaluationInfo> {
4037
return getRelevantManagers(ctx).map {
41-
ApiEvaluationInfo(it)
38+
ApiClientEvaluationInfo(it)
4239
}
4340
}
4441
}

backend/src/main/kotlin/dev/dres/api/rest/handler/evaluation/client/ClientTaskInfoHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import jetbrains.exodus.database.TransientEntityStore
2222
*/
2323
class ClientTaskInfoHandler : AbstractEvaluationClientHandler(),
2424
GetRestHandler<ApiTaskTemplateInfo> {
25-
override val route = "client/evaluation/currentTask/{runId}"
25+
override val route = "client/evaluation/currentTask/{evaluationId}"
2626

2727
@OpenApi(
2828
summary = "Returns an overview of the currently active task for a run.",
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package dev.dres.api.rest.types.evaluation
2+
3+
import dev.dres.data.model.run.ApiRunProperties
4+
import dev.dres.run.InteractiveAsynchronousRunManager
5+
import dev.dres.run.InteractiveSynchronousRunManager
6+
import dev.dres.run.NonInteractiveRunManager
7+
import dev.dres.run.RunManager
8+
9+
/**
10+
* Contains the basic and most importantly static information about a [RunManager] that is relevant to a participant.
11+
*
12+
*/
13+
data class ApiClientEvaluationInfo(
14+
val id: String,
15+
val name: String,
16+
val type: ApiEvaluationType,
17+
val status: ApiEvaluationStatus,
18+
val templateId: String,
19+
val templateDescription: String?,
20+
val teams: List<String>,
21+
val taskTemplates: List<ApiClientTaskTemplateInfo>,
22+
) {
23+
constructor(manager: RunManager): this(
24+
manager.id,
25+
manager.name,
26+
when(manager) {
27+
is InteractiveSynchronousRunManager -> ApiEvaluationType.SYNCHRONOUS
28+
is InteractiveAsynchronousRunManager -> ApiEvaluationType.ASYNCHRONOUS
29+
is NonInteractiveRunManager -> ApiEvaluationType.NON_INTERACTIVE
30+
else -> throw IllegalStateException("Incompatible type of run manager.")
31+
},
32+
manager.status.toApi(),
33+
manager.template.id,
34+
manager.template.description,
35+
manager.template.teams.asSequence().map { team -> team.name ?: "" }.toList(),
36+
manager.template.tasks.map { task -> ApiClientTaskTemplateInfo(task) }.toList()
37+
)
38+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package dev.dres.api.rest.types.evaluation
2+
3+
import dev.dres.api.rest.types.template.tasks.ApiTaskTemplate
4+
import dev.dres.data.model.template.task.DbTaskTemplate
5+
6+
/**
7+
* Basic and most importantly static information about a [DbTaskTemplate] relevant to the participant.
8+
*/
9+
data class ApiClientTaskTemplateInfo(
10+
val name: String,
11+
val taskGroup: String,
12+
val taskType: String,
13+
val duration: Long
14+
) {
15+
constructor(task: ApiTaskTemplate) : this(
16+
task.name,
17+
task.taskGroup,
18+
task.taskType,
19+
task.duration
20+
)
21+
}

backend/src/main/kotlin/dev/dres/mgmt/TemplateManager.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,12 +386,16 @@ object TemplateManager {
386386
}
387387
}
388388
}
389+
390+
println("start rendering ${segmentTasks.size} videos")
391+
389392
await.all {
390393
try {
391-
it.get(60, TimeUnit.SECONDS)
394+
val result = it.get(3, TimeUnit.MINUTES)
395+
println("completed rendering of $result")
392396
true
393397
} catch (e: Throwable) {
394-
throw IllegalStateException("Required media file could not be prepared.")
398+
throw IllegalStateException("Required media file could not be prepared: ${e.message}")
395399
}
396400
}
397401

doc/oas-client.json

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"openapi" : "3.0.3",
33
"info" : {
44
"title" : "DRES Client API",
5-
"description" : "Client API for DRES (Distributed Retrieval Evaluation Server), Version 2.0.0",
6-
"version" : "2.0.0"
5+
"description" : "Client API for DRES (Distributed Retrieval Evaluation Server), Version 2.0.0-RC2",
6+
"version" : "2.0.0-RC2"
77
},
88
"paths" : {
99
"/api/v1/submit" : {
@@ -237,7 +237,7 @@
237237
"schema" : {
238238
"type" : "array",
239239
"items" : {
240-
"$ref" : "#/components/schemas/ApiEvaluationInfo"
240+
"$ref" : "#/components/schemas/ApiClientEvaluationInfo"
241241
}
242242
}
243243
}
@@ -1228,6 +1228,63 @@
12281228
"type" : "string",
12291229
"enum" : [ "FRAME_NUMBER", "SECONDS", "MILLISECONDS", "TIMECODE" ]
12301230
},
1231+
"ApiClientEvaluationInfo" : {
1232+
"type" : "object",
1233+
"additionalProperties" : false,
1234+
"properties" : {
1235+
"id" : {
1236+
"type" : "string"
1237+
},
1238+
"name" : {
1239+
"type" : "string"
1240+
},
1241+
"type" : {
1242+
"$ref" : "#/components/schemas/ApiEvaluationType"
1243+
},
1244+
"status" : {
1245+
"$ref" : "#/components/schemas/ApiEvaluationStatus"
1246+
},
1247+
"templateId" : {
1248+
"type" : "string"
1249+
},
1250+
"templateDescription" : {
1251+
"type" : "string"
1252+
},
1253+
"teams" : {
1254+
"type" : "array",
1255+
"items" : {
1256+
"type" : "string"
1257+
}
1258+
},
1259+
"taskTemplates" : {
1260+
"type" : "array",
1261+
"items" : {
1262+
"$ref" : "#/components/schemas/ApiClientTaskTemplateInfo"
1263+
}
1264+
}
1265+
},
1266+
"required" : [ "id", "name", "type", "status", "templateId", "teams", "taskTemplates" ]
1267+
},
1268+
"ApiClientTaskTemplateInfo" : {
1269+
"type" : "object",
1270+
"additionalProperties" : false,
1271+
"properties" : {
1272+
"name" : {
1273+
"type" : "string"
1274+
},
1275+
"taskGroup" : {
1276+
"type" : "string"
1277+
},
1278+
"taskType" : {
1279+
"type" : "string"
1280+
},
1281+
"duration" : {
1282+
"type" : "integer",
1283+
"format" : "int64"
1284+
}
1285+
},
1286+
"required" : [ "name", "taskGroup", "taskType", "duration" ]
1287+
},
12311288
"ApiEvaluation" : {
12321289
"type" : "object",
12331290
"additionalProperties" : false,

0 commit comments

Comments
 (0)