Skip to content

Commit 9307da0

Browse files
authored
Return both file number and db number from configure methods
Wrapping the configuration retrieved from the DB along with the latest file number tracked on the file system makes it easier to debug issues with the scan number returned not matching what is expected without having to modify the DB. Now that the graphQL entity is the wrapped configuration, the tracker_file_extension can be reinstated on the underlying BeamlineConfiguration instead of being exposed as a public field.
1 parent ef1b451 commit 9307da0

File tree

3 files changed

+102
-37
lines changed

3 files changed

+102
-37
lines changed

src/db_service.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub struct BeamlineConfiguration {
6666
visit: RawPathTemplate<VisitTemplate>,
6767
scan: RawPathTemplate<ScanTemplate>,
6868
detector: RawPathTemplate<DetectorTemplate>,
69-
pub(crate) tracker_file_extension: Option<String>,
69+
tracker_file_extension: Option<String>,
7070
}
7171

7272
impl BeamlineConfiguration {
@@ -89,6 +89,10 @@ impl BeamlineConfiguration {
8989
pub fn detector(&self) -> SqliteTemplateResult<DetectorField> {
9090
self.detector.as_template()
9191
}
92+
93+
pub fn tracker_file_extension(&self) -> Option<&str> {
94+
self.tracker_file_extension.as_deref()
95+
}
9296
}
9397

9498
impl<'r> FromRow<'r, SqliteRow> for BeamlineConfiguration {

src/graphql.rs

Lines changed: 86 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ struct ScanPaths {
147147
subdirectory: Subdirectory,
148148
}
149149

150+
/// GraphQL type to provide current configuration for a beamline
151+
struct CurrentConfiguration {
152+
db_config: BeamlineConfiguration,
153+
high_file: Option<u32>,
154+
}
155+
150156
/// Error to be returned when a path contains non-unicode characters
151157
#[derive(Debug)]
152158
struct NonUnicodePath;
@@ -243,21 +249,24 @@ impl ScanPaths {
243249
}
244250

245251
#[Object]
246-
impl BeamlineConfiguration {
252+
impl CurrentConfiguration {
247253
pub async fn visit_template(&self) -> async_graphql::Result<String> {
248-
Ok(self.visit()?.to_string())
254+
Ok(self.db_config.visit()?.to_string())
249255
}
250256
pub async fn scan_template(&self) -> async_graphql::Result<String> {
251-
Ok(self.scan()?.to_string())
257+
Ok(self.db_config.scan()?.to_string())
252258
}
253259
pub async fn detector_template(&self) -> async_graphql::Result<String> {
254-
Ok(self.detector()?.to_string())
260+
Ok(self.db_config.detector()?.to_string())
261+
}
262+
pub async fn db_scan_number(&self) -> async_graphql::Result<u32> {
263+
Ok(self.db_config.scan_number())
255264
}
256-
pub async fn latest_scan_number(&self) -> async_graphql::Result<u32> {
257-
Ok(self.scan_number())
265+
pub async fn file_scan_number(&self) -> async_graphql::Result<Option<u32>> {
266+
Ok(self.high_file)
258267
}
259268
pub async fn tracker_file_extension(&self) -> async_graphql::Result<Option<&str>> {
260-
Ok(self.tracker_file_extension.as_deref())
269+
Ok(self.db_config.tracker_file_extension())
261270
}
262271
}
263272

@@ -299,11 +308,20 @@ impl Query {
299308
&self,
300309
ctx: &Context<'_>,
301310
beamline: String,
302-
) -> async_graphql::Result<BeamlineConfiguration> {
311+
) -> async_graphql::Result<CurrentConfiguration> {
303312
check_auth(ctx, |policy, token| policy.check_admin(token, &beamline)).await?;
304313
let db = ctx.data::<SqliteScanPathService>()?;
314+
let nt = ctx.data::<NumTracker>()?;
305315
trace!("Getting config for {beamline:?}");
306-
Ok(db.current_configuration(&beamline).await?)
316+
let conf = db.current_configuration(&beamline).await?;
317+
let dir = nt
318+
.for_beamline(&beamline, conf.tracker_file_extension())
319+
.await?;
320+
let high_file = dir.prev().await?;
321+
Ok(CurrentConfiguration {
322+
db_config: conf,
323+
high_file,
324+
})
307325
}
308326
}
309327

@@ -329,7 +347,7 @@ impl Mutation {
329347
// isn't much we can do from here.
330348
let current = db.current_configuration(&beamline).await?;
331349
let dir = nt
332-
.for_beamline(&beamline, current.tracker_file_extension.as_deref())
350+
.for_beamline(&beamline, current.tracker_file_extension())
333351
.await?;
334352

335353
let next_scan = db
@@ -355,15 +373,24 @@ impl Mutation {
355373
ctx: &Context<'ctx>,
356374
beamline: String,
357375
config: ConfigurationUpdates,
358-
) -> async_graphql::Result<BeamlineConfiguration> {
376+
) -> async_graphql::Result<CurrentConfiguration> {
359377
check_auth(ctx, |pc, token| pc.check_admin(token, &beamline)).await?;
360378
let db = ctx.data::<SqliteScanPathService>()?;
379+
let nt = ctx.data::<NumTracker>()?;
361380
trace!("Configuring: {beamline}: {config:?}");
362-
let upd = config.into_update(beamline);
363-
match upd.update_beamline(db).await? {
364-
Some(bc) => Ok(bc),
365-
None => Ok(upd.insert_new(db).await?),
366-
}
381+
let upd = config.into_update(&beamline);
382+
let db_config = match upd.update_beamline(db).await? {
383+
Some(bc) => bc,
384+
None => upd.insert_new(db).await?,
385+
};
386+
let dir = nt
387+
.for_beamline(&beamline, db_config.tracker_file_extension())
388+
.await?;
389+
let high_file = dir.prev().await?;
390+
Ok(CurrentConfiguration {
391+
db_config,
392+
high_file,
393+
})
367394
}
368395
}
369396

@@ -395,9 +422,9 @@ struct ConfigurationUpdates {
395422
}
396423

397424
impl ConfigurationUpdates {
398-
fn into_update(self, name: String) -> BeamlineConfigurationUpdate {
425+
fn into_update<S: Into<String>>(self, name: S) -> BeamlineConfigurationUpdate {
399426
BeamlineConfigurationUpdate {
400-
name,
427+
name: name.into(),
401428
scan_number: self.scan_number,
402429
visit: self.visit.map(|t| t.0),
403430
scan: self.scan.map(|t| t.0),
@@ -623,15 +650,15 @@ mod tests {
623650
Some(122),
624651
None,
625652
);
626-
cfg.into_update("i22".into()).insert_new(&db).await.unwrap();
653+
cfg.into_update("i22").insert_new(&db).await.unwrap();
627654
let cfg = updates(
628655
Some("/tmp/{instrument}/data/{visit}/"),
629656
Some("{subdirectory}/{instrument}-{scan_number}"),
630657
Some("{subdirectory}/{scan_number}/{instrument}-{scan_number}-{detector}"),
631658
Some(621),
632659
Some("b21_ext"),
633660
);
634-
cfg.into_update("b21".into()).insert_new(&db).await.unwrap();
661+
cfg.into_update("b21").insert_new(&db).await.unwrap();
635662
db
636663
}
637664

@@ -744,15 +771,15 @@ mod tests {
744771
async fn configuration(#[future(awt)] env: TestEnv) {
745772
let query = r#"{
746773
configuration(beamline: "i22") {
747-
visitTemplate scanTemplate detectorTemplate latestScanNumber trackerFileExtension
774+
visitTemplate scanTemplate detectorTemplate dbScanNumber trackerFileExtension
748775
}}"#;
749776
let result = env.schema.execute(query).await;
750777
let exp = value!({
751778
"configuration": {
752779
"visitTemplate": "/tmp/{instrument}/data/{visit}",
753780
"scanTemplate": "{subdirectory}/{instrument}-{scan_number}",
754781
"detectorTemplate": "{subdirectory}/{instrument}-{scan_number}-{detector}",
755-
"latestScanNumber": 122,
782+
"dbScanNumber": 122,
756783
"trackerFileExtension": Value::Null
757784
}});
758785
assert!(result.errors.is_empty());
@@ -773,12 +800,45 @@ mod tests {
773800
);
774801
}
775802

803+
#[rstest]
804+
#[tokio::test]
805+
async fn configuration_with_mismatched_numbers(
806+
#[future(awt)] env: TestEnv,
807+
) -> Result<(), Box<dyn Error>> {
808+
tokio::fs::File::create_new(env.dir.as_ref().join("i22").join("5678.i22"))
809+
.await
810+
.unwrap();
811+
let query = r#"{
812+
configuration(beamline: "i22") {
813+
dbScanNumber
814+
fileScanNumber
815+
}
816+
}"#;
817+
let result = env.schema.execute(query).await;
818+
let exp = value!({
819+
"configuration": {
820+
"dbScanNumber": 122,
821+
"fileScanNumber": 5678
822+
}
823+
});
824+
assert!(result.errors.is_empty());
825+
assert_eq!(result.data, exp);
826+
827+
let db_num = env.db.current_configuration("i22").await?.scan_number();
828+
let file_num = env.dir.as_ref().join("i22").join("5678.i22");
829+
let next_file_num = env.dir.as_ref().join("i22").join("5679.i22");
830+
assert_eq!(db_num, 122);
831+
assert!(file_num.exists());
832+
assert!(!next_file_num.exists());
833+
Ok(())
834+
}
835+
776836
#[rstest]
777837
#[tokio::test]
778838
async fn empty_configure_for_existing(#[future(awt)] env: TestEnv) {
779839
let query = r#"mutation {
780840
configure(beamline: "i22", config: {}) {
781-
visitTemplate scanTemplate detectorTemplate latestScanNumber
841+
visitTemplate scanTemplate detectorTemplate dbScanNumber
782842
}
783843
}"#;
784844
let result = env.schema.execute(query).await;
@@ -787,7 +847,7 @@ mod tests {
787847
"visitTemplate": "/tmp/{instrument}/data/{visit}",
788848
"scanTemplate": "{subdirectory}/{instrument}-{scan_number}",
789849
"detectorTemplate": "{subdirectory}/{instrument}-{scan_number}-{detector}",
790-
"latestScanNumber": 122
850+
"dbScanNumber": 122
791851
}
792852
});
793853
println!("{result:#?}");
@@ -836,7 +896,7 @@ mod tests {
836896
scan: "{instrument}-{scan_number}"
837897
detector: "{scan_number}-{detector}"
838898
}) {
839-
scanTemplate visitTemplate detectorTemplate latestScanNumber
899+
scanTemplate visitTemplate detectorTemplate dbScanNumber
840900
}
841901
}"#,
842902
)
@@ -845,7 +905,7 @@ mod tests {
845905
"visitTemplate": "/tmp/{instrument}/{year}/{visit}",
846906
"scanTemplate": "{instrument}-{scan_number}",
847907
"detectorTemplate": "{scan_number}-{detector}",
848-
"latestScanNumber": 0
908+
"dbScanNumber": 0
849909
} });
850910
assert!(result.errors.is_empty());
851911
assert_eq!(result.data, exp);

static/service_schema

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
type BeamlineConfiguration {
2-
visitTemplate: String!
3-
scanTemplate: String!
4-
detectorTemplate: String!
5-
latestScanNumber: Int!
6-
trackerFileExtension: String
7-
}
8-
91

102
input ConfigurationUpdates {
113
visit: VisitTemplate
@@ -15,6 +7,15 @@ input ConfigurationUpdates {
157
trackerFileExtension: String
168
}
179

10+
type CurrentConfiguration {
11+
visitTemplate: String!
12+
scanTemplate: String!
13+
detectorTemplate: String!
14+
dbScanNumber: Int!
15+
fileScanNumber: Int
16+
trackerFileExtension: String
17+
}
18+
1819
scalar Detector
1920

2021
"""
@@ -40,12 +41,12 @@ type Mutation {
4041
Access scan file locations for the next scan
4142
"""
4243
scan(beamline: String!, visit: String!, sub: Subdirectory): ScanPaths!
43-
configure(beamline: String!, config: ConfigurationUpdates!): BeamlineConfiguration!
44+
configure(beamline: String!, config: ConfigurationUpdates!): CurrentConfiguration!
4445
}
4546

4647
type Query {
4748
paths(beamline: String!, visit: String!): VisitPath!
48-
configuration(beamline: String!): BeamlineConfiguration!
49+
configuration(beamline: String!): CurrentConfiguration!
4950
}
5051

5152
type ScanPaths {

0 commit comments

Comments
 (0)