Skip to content

Commit f215d1b

Browse files
Optimize s3 url generation
1 parent 708cb79 commit f215d1b

File tree

7 files changed

+83
-84
lines changed

7 files changed

+83
-84
lines changed

charts/processed_data/charts/processed_data/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ type: application
55

66
version: 0.1.0
77

8-
appVersion: 0.1.0-rc13
8+
appVersion: 0.2.0-rc2
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: bitnami.com/v1alpha1
2+
kind: SealedSecret
3+
metadata:
4+
annotations:
5+
sealedsecrets.bitnami.com/namespace-wide: "true"
6+
creationTimestamp: null
7+
name: ispyb
8+
namespace: graph
9+
spec:
10+
encryptedData:
11+
password: AgAE9My2sdmPfJCuKFPt5O6CBCAGytIlcrChly3IH2s70PlM/B41Lj4dXId1pCGsZkCtx0CTOfDp6+oJbyP0LA8i7qJkZFqBB/bZpsEU3HR/ki/5//xXyepKoUSbFd3Gu3UFNBVZCTqnMClms9HFVyFaoARYKc3gKLO/CqSbFl+7dWurXO4DC0VvQpmHEZ3MVIrU7b53YPV9r1VbrTntvFwvdM/SBXhNuZVQVeHJmrdbiewSbRLUxSoRWy394PfdHV05LWOVcKkGOHbh9PoJuefu+5j6Xc3H1P1YWteH/0/u67Cnjx2193LU4GJxexoQjBUY6O5EkeOwE5N1hM7xyNPPndCQEHYfSHSZWKR9m6Q8OGAMp/JHIiOiwX/li81Q9s30x0pcNRNjr//+Bxo1eVI1TzXlQ1M8RO2r4q774p7jGtXzo7fhBfjPHm3K0LD4WJovemVybjj2eAwlI+i3b3K56/s6JqdOa42LydxjxZu6LXlWLUKpxE3uQ9SE7RyHq1thWdD2OnR+BjXfoYIaoGVcTiJQpk34zorSgIpwN4WqdTFFM9x/yCrMTAl2gA7AjTNGrTlaTjU7ypbzjwubGDwxCW3XXRTqdlTi0ShEsyT2yqIZQWvibbTUc5GICHsyfcjudmarWZ4VDR9UV4XPRb8cHEJehVhBC8ugxg3ioCv3+AsLv5MOLZfVC+vAHDGyJ6x+XRRZdY8BwJOzEss=
12+
template:
13+
metadata:
14+
annotations:
15+
sealedsecrets.bitnami.com/namespace-wide: "true"
16+
creationTimestamp: null
17+
name: ispyb
18+
namespace: graph
19+

charts/processed_data/values.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,17 @@ processed-data:
88
secretName: ispyb
99
secretKey: password
1010
otelCollectorUrl: http://federation-opentelemetry-collector:4317
11+
affinity:
12+
podAffinity:
13+
requiredDuringSchedulingIgnoredDuringExecution:
14+
- labelSelector:
15+
matchExpressions:
16+
- key: app.kubernetes.io/instance
17+
operator: In
18+
values:
19+
- ispyb
20+
- key: app.kubernetes.io/name
21+
operator: In
22+
values:
23+
- mariadb-galera
24+
topologyKey: kubernetes.io/hostname

processed_data/src/graphql/entities.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ impl From<Option<FileType>> for AttachmentFileType {
117117
#[graphql(name = "AutoProcFileAttachment", unresolvable, complex)]
118118
pub struct AutoProcFileAttachment {
119119
/// An opaque unique identifier for the autoproc file attachment
120+
#[graphql(skip)]
120121
pub id: u32,
121122
/// An opaque unique identifier for auto proc program
122123
#[graphql(skip)]
@@ -130,7 +131,6 @@ pub struct AutoProcFileAttachment {
130131
#[graphql(skip)]
131132
pub file_path: Option<String>,
132133
}
133-
134134
impl From<auto_proc_program_attachment::Model> for AutoProcFileAttachment {
135135
fn from(value: auto_proc_program_attachment::Model) -> Self {
136136
Self {
@@ -143,6 +143,19 @@ impl From<auto_proc_program_attachment::Model> for AutoProcFileAttachment {
143143
}
144144
}
145145

146+
impl AutoProcFileAttachment {
147+
/// S3 bucket object key
148+
pub fn object_key(&self) -> String {
149+
let mut key = std::path::PathBuf::from(
150+
<Option<String> as Clone>::clone(&self.file_path)
151+
.unwrap()
152+
.to_string(),
153+
);
154+
key.push(<Option<String> as Clone>::clone(&self.file_name).unwrap());
155+
key.to_string_lossy().to_string()
156+
}
157+
}
158+
146159
/// Represents a processing job
147160
#[derive(Clone, Debug, PartialEq, SimpleObject)]
148161
#[graphql(name = "ProcessingJobs", unresolvable)]
@@ -272,19 +285,6 @@ impl From<auto_proc_scaling_statistics::Model> for AutoProcScalingStatics {
272285
}
273286
}
274287

275-
impl AutoProcFileAttachment {
276-
/// S3 bucket object key
277-
pub fn object_key(&self) -> String {
278-
let mut key = std::path::PathBuf::from(
279-
<Option<String> as Clone>::clone(&self.file_path)
280-
.unwrap()
281-
.to_string(),
282-
);
283-
key.push(<Option<String> as Clone>::clone(&self.file_name).unwrap());
284-
key.to_string_lossy().to_string()
285-
}
286-
}
287-
288288
/// Datasets subgraph extension
289289
#[derive(SimpleObject)]
290290
#[graphql(name = "DataCollection", complex)]

processed_data/src/graphql/mod.rs

Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use async_graphql::{
55
dataloader::{DataLoader, Loader},
66
ComplexObject, Context, EmptyMutation, EmptySubscription, Object, Schema, SchemaBuilder,
77
};
8-
use aws_sdk_s3::{presigning::PresigningConfig, Client};
8+
use aws_sdk_s3::presigning::PresigningConfig;
99
use entities::{
1010
AutoProcFileAttachment, AutoProcScalingStatics, AutoProcessing, DataCollection, ProcessingJob,
1111
StatisticsType,
@@ -29,23 +29,13 @@ pub type RootSchema = Schema<Query, EmptyMutation, EmptySubscription>;
2929
/// router handler extension
3030
pub trait AddDataLoadersExt {
3131
/// Adds dataloader to graphql request
32-
fn add_data_loaders(
33-
self,
34-
database: DatabaseConnection,
35-
s3_client: Client,
36-
s3_bucket: S3Bucket,
37-
) -> Self;
32+
fn add_data_loaders(self, database: DatabaseConnection) -> Self;
3833
}
3934

4035
impl AddDataLoadersExt for async_graphql::Request {
41-
fn add_data_loaders(
42-
self,
43-
database: DatabaseConnection,
44-
s3_client: Client,
45-
s3_bucket: S3Bucket,
46-
) -> Self {
36+
fn add_data_loaders(self, database: DatabaseConnection) -> Self {
4737
self.data(DataLoader::new(
48-
FileAttachmentDataLoader::new(database.clone(), s3_client, s3_bucket),
38+
FileAttachmentDataLoader::new(database.clone()),
4939
tokio::spawn,
5040
))
5141
.data(DataLoader::new(
@@ -77,8 +67,6 @@ pub struct Query;
7767
pub struct FileAttachmentDataLoader {
7868
database: DatabaseConnection,
7969
parent_span: Span,
80-
s3_client: Client,
81-
s3_bucket: S3Bucket,
8270
}
8371
/// DataLoader for Process Job
8472
#[allow(clippy::missing_docs_in_private_items)]
@@ -111,12 +99,10 @@ impl ProcessingJobDataLoader {
11199

112100
#[allow(clippy::missing_docs_in_private_items)]
113101
impl FileAttachmentDataLoader {
114-
fn new(database: DatabaseConnection, s3_client: Client, s3_bucket: S3Bucket) -> Self {
102+
fn new(database: DatabaseConnection) -> Self {
115103
Self {
116104
database,
117105
parent_span: Span::current(),
118-
s3_client,
119-
s3_bucket,
120106
}
121107
}
122108
}
@@ -372,25 +358,6 @@ impl DataCollection {
372358
}
373359
}
374360

375-
#[ComplexObject]
376-
impl AutoProcFileAttachment {
377-
/// Gives downloadable link for the processed image in the s3 bucket
378-
async fn file_url(&self, ctx: &Context<'_>) -> async_graphql::Result<String> {
379-
let s3_client = ctx.data::<aws_sdk_s3::Client>()?;
380-
let bucket = ctx.data::<S3Bucket>()?;
381-
let object_uri = s3_client
382-
.get_object()
383-
.bucket(bucket.clone())
384-
.key(self.object_key())
385-
.presigned(PresigningConfig::expires_in(Duration::from_secs(10 * 60))?)
386-
.await?
387-
.uri()
388-
.clone();
389-
let object_url = Url::parse(&object_uri.to_string())?;
390-
Ok(object_url.to_string())
391-
}
392-
}
393-
394361
#[ComplexObject]
395362
impl AutoProcessing {
396363
/// Fetches the overall scaling statistics type
@@ -442,6 +409,25 @@ impl AutoProcessing {
442409
}
443410
}
444411

412+
#[ComplexObject]
413+
impl AutoProcFileAttachment {
414+
/// Gives downloadable link for the processed image in the s3 bucket
415+
async fn file_url(&self, ctx: &Context<'_>) -> async_graphql::Result<String> {
416+
let s3_client = ctx.data::<aws_sdk_s3::Client>()?;
417+
let bucket = ctx.data::<S3Bucket>()?;
418+
let object_uri = s3_client
419+
.get_object()
420+
.bucket(bucket.clone())
421+
.key(self.object_key())
422+
.presigned(PresigningConfig::expires_in(Duration::from_secs(10 * 60))?)
423+
.await?
424+
.uri()
425+
.clone();
426+
let object_url = Url::parse(&object_uri.to_string())?;
427+
Ok(object_url.to_string())
428+
}
429+
}
430+
445431
#[Object]
446432
impl Query {
447433
/// Reference datasets resolver for the router

processed_data/src/main.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,7 @@ async fn setup_database(database_url: Url) -> Result<DatabaseConnection, Transac
144144
}
145145

146146
/// Creates an [`axum::Router`] serving GraphiQL, synchronous GraphQL and GraphQL subscriptions
147-
fn setup_router(
148-
schema: RootSchema,
149-
database: DatabaseConnection,
150-
s3_client: aws_sdk_s3::Client,
151-
s3_bucket: S3Bucket,
152-
) -> Router {
147+
fn setup_router(schema: RootSchema, database: DatabaseConnection) -> Router {
153148
#[allow(clippy::missing_docs_in_private_items)]
154149
const GRAPHQL_ENDPOINT: &str = "/";
155150

@@ -159,7 +154,7 @@ fn setup_router(
159154
get(Html(
160155
GraphiQLSource::build().endpoint(GRAPHQL_ENDPOINT).finish(),
161156
))
162-
.post(GraphQLHandler::new(schema, database, s3_client, s3_bucket)),
157+
.post(GraphQLHandler::new(schema, database)),
163158
)
164159
.layer(OtelInResponseLayer)
165160
.layer(OtelAxumLayer::default())
@@ -248,8 +243,11 @@ async fn main() {
248243
setup_telemetry(args.log_level, args.otel_collector_url).unwrap();
249244
let database = setup_database(args.database_url).await.unwrap();
250245
let s3_client = Client::from_s3_client_args(args.s3_client);
251-
let schema = root_schema_builder().finish();
252-
let router = setup_router(schema, database, s3_client, args.s3_bucket);
246+
let schema = root_schema_builder()
247+
.data(s3_client)
248+
.data(args.s3_bucket)
249+
.finish();
250+
let router = setup_router(schema, database);
253251
serve(router, args.port).await.unwrap();
254252
}
255253
Cli::Schema(args) => {

processed_data/src/route_handlers.rs

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use axum::{
1010
use sea_orm::DatabaseConnection;
1111
use std::{future::Future, pin::Pin};
1212

13-
use crate::{graphql::AddDataLoadersExt, S3Bucket};
13+
use crate::graphql::AddDataLoadersExt;
1414

1515
/// An [`Handler`] which executes an [`Executor`] including the [`Authorization<Bearer>`] in the [`async_graphql::Context`]
1616
#[derive(Debug, Clone)]
@@ -19,26 +19,12 @@ pub struct GraphQLHandler<E: Executor> {
1919
executor: E,
2020
/// Database connection
2121
database: DatabaseConnection,
22-
/// S3 client
23-
s3_client: aws_sdk_s3::Client,
24-
/// S3 Bucket
25-
s3_bucket: S3Bucket,
2622
}
2723

2824
impl<E: Executor> GraphQLHandler<E> {
2925
/// Constructs an instance of the handler with the provided schema.
30-
pub fn new(
31-
executor: E,
32-
database: DatabaseConnection,
33-
s3_client: aws_sdk_s3::Client,
34-
s3_bucket: S3Bucket,
35-
) -> Self {
36-
Self {
37-
executor,
38-
database,
39-
s3_client,
40-
s3_bucket,
41-
}
26+
pub fn new(executor: E, database: DatabaseConnection) -> Self {
27+
Self { executor, database }
4228
}
4329
}
4430

@@ -54,11 +40,7 @@ where
5440
match request {
5541
Ok(request) => GraphQLResponse::from(
5642
self.executor
57-
.execute(request.into_inner().add_data_loaders(
58-
self.database,
59-
self.s3_client,
60-
self.s3_bucket,
61-
))
43+
.execute(request.into_inner().add_data_loaders(self.database))
6244
.await,
6345
)
6446
.into_response(),

0 commit comments

Comments
 (0)