-
Notifications
You must be signed in to change notification settings - Fork 2
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
Revamp JoinRecords #93
Open
WillNilges
wants to merge
39
commits into
main
Choose a base branch
from
wdn/updated-s3-submissions
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
39 commits
Select commit
Hold shift + click to select a range
7e5ea5d
Stub out updating S3 submissions with httpCode
WillNilges 799a96a
checkpoint
WillNilges a5635a8
Add replay stats on JoinRecords
WillNilges 68a40d4
what the fuck amazon
WillNilges c44f157
Shit now I need S3 in the github tests
WillNilges 397984c
First wack updating github tests
WillNilges 211c405
change a million things
WillNilges 7562d4d
Checkpoint. Need to update JoinRecord here to match MeshDB
WillNilges 0912cdc
checkpoint
WillNilges 280271e
Nullable install Number. Make tests pass
WillNilges 3439e9b
Merge branch 'main' into wdn/updated-s3-submissions
WillNilges 4feb9d9
pretty
WillNilges e61fe71
checkpoint
WillNilges 31b55ad
This is kinda jank
WillNilges cb0e38a
Add submission time
WillNilges 01591a0
Submission time part 2
WillNilges 03aad06
Add Join Record to more tests
WillNilges 6e619dc
pretty
WillNilges 4d9c466
chom
WillNilges 7798ec2
pretty
WillNilges f5c2c0a
Gracefully handle S3 misconfiguration.
WillNilges 0f9bdde
pretty
WillNilges 65b1a2a
i just crashed kde
WillNilges 1c50579
it's the whole fucking point
WillNilges 14c81f6
type type type
WillNilges 1ca0ab9
if you crash one more time I am going to atomize your entire bloodline
WillNilges beae3d2
i completely broke everything
WillNilges ceb320d
ugh
WillNilges deda4b6
ugh
WillNilges 1a1e195
fuck dirty
WillNilges 9d355d2
Delete shotgun debugs
WillNilges f06e7f7
pretty
WillNilges 74a4de1
fix github action
WillNilges a888508
Fix(?) github action
WillNilges 328af23
Cleanup
WillNilges 923029a
Delete demo test
WillNilges d1a7b45
Add test for meshdb being hard down
WillNilges 50586c1
Tests are failing when run in parallel. Probably some nonsense with b…
WillNilges 0037c61
Maybe this will work too
WillNilges File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,17 @@ | ||
MESHDB_URL=http://127.0.0.1:8000 | ||
NEXT_PUBLIC_MESHDB_URL=http://127.0.0.1:8000 | ||
|
||
JOIN_RECORD_BUCKET_NAME=meshdb-join-form-log | ||
JOIN_RECORD_PREFIX=dev-join-form-submissions | ||
|
||
S3_ENDPOINT=http://127.0.0.1:9000 | ||
AWS_ACCESS_KEY=sampleaccesskey | ||
AWS_SECRET_KEY=samplesecretkey | ||
AWS_REGION=us-east-1 | ||
|
||
# Docker compose environment variables | ||
# Set this to true in prod | ||
COMPOSE_EXTERNAL_NETWORK=false | ||
# Set this to traefik-net in prod | ||
COMPOSE_NETWORK_NAME= | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
"use server"; | ||
// import { access, constants, appendFileSync, readFile } from "node:fs"; | ||
import { | ||
S3Client, | ||
PutObjectCommand, | ||
GetObjectCommand, | ||
ListBucketsCommand, | ||
} from "@aws-sdk/client-s3"; | ||
import { JoinFormValues } from "@/components/JoinForm/JoinForm"; | ||
import { Readable } from "stream"; | ||
import { JoinRecord } from "./types"; | ||
|
||
// const JOIN_FORM_LOG = process.env.JOIN_FORM_LOG as string; | ||
|
||
class JoinRecordS3 { | ||
private s3Client: S3Client; | ||
|
||
private BUCKET_NAME: string; | ||
private PREFIX: string; | ||
|
||
private S3_ENDPOINT: string; | ||
private AWS_ACCESS_KEY_ID: string; | ||
private AWS_SECRET_ACCESS_KEY: string; | ||
|
||
constructor() { | ||
this.BUCKET_NAME = process.env.JOIN_RECORD_BUCKET_NAME as string; | ||
this.PREFIX = process.env.JOIN_RECORD_PREFIX as string; | ||
this.S3_ENDPOINT = process.env.S3_ENDPOINT as string; | ||
this.AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID as string; | ||
this.AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY as string; | ||
|
||
// Setup the S3 client | ||
this.s3Client = new S3Client({ | ||
endpoint: | ||
this.S3_ENDPOINT != undefined | ||
? this.S3_ENDPOINT | ||
: "https://s3.us-east-1.amazonaws.com", | ||
}); | ||
} | ||
|
||
// Records the submission we just got as a JSON object in an S3 bucket. | ||
// submission: A Join Form Submission. We append a few things to this. | ||
// key: The S3 path we store the submission at | ||
// responseCode: If we have a response code for this submission, add it here. | ||
async save(joinRecord: JoinRecord, key: string = "") { | ||
// Check if the S3 client is working and exit gracefully with a warning if it is not. | ||
try { | ||
const command = new ListBucketsCommand({}); | ||
await this.s3Client.send(command); | ||
} catch (error) { | ||
console.warn( | ||
"S3 Client not configured properly. I WILL NOT SAVE THIS SUBMISSION.", | ||
error, | ||
); | ||
return; | ||
} | ||
|
||
// Get the date to store this submission under (this is part of the path) | ||
const submissionKey = joinRecord.submission_time | ||
.replace(/[-:T]/g, "/") | ||
.slice(0, 19); | ||
|
||
// Create the path, or use the one provided. | ||
key = key != "" ? key : `${this.PREFIX}/${submissionKey}.json`; | ||
|
||
let body = JSON.stringify(joinRecord); | ||
|
||
const command = new PutObjectCommand({ | ||
Bucket: this.BUCKET_NAME, | ||
Key: key, | ||
Body: body, | ||
}); | ||
|
||
try { | ||
const response = await this.s3Client.send(command); | ||
console.log(response); | ||
} catch (err) { | ||
// Oof, guess we'll drop this on the floor. | ||
console.error(err); | ||
throw err; | ||
} | ||
|
||
// Return the key later so we can update it. | ||
return key; | ||
} | ||
|
||
// Gets the contents of a JoinRecord for testing | ||
async get(key: string) { | ||
const getObjectCommand = new GetObjectCommand({ | ||
Bucket: this.BUCKET_NAME, | ||
Key: key, | ||
}); | ||
const getObjectResponse = await this.s3Client.send(getObjectCommand); | ||
|
||
if (getObjectResponse.Body) { | ||
const content = await this.streamToString( | ||
getObjectResponse.Body as Readable, | ||
); | ||
return JSON.parse(content); | ||
} | ||
throw new Error("Could not get Record from S3"); | ||
} | ||
|
||
// Decode S3 response | ||
async streamToString(stream: Readable): Promise<string> { | ||
return await new Promise((resolve, reject) => { | ||
const chunks: Buffer[] = []; | ||
stream.on("data", (chunk) => chunks.push(chunk)); | ||
stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8"))); | ||
stream.on("error", reject); | ||
}); | ||
} | ||
} | ||
|
||
const joinRecordS3 = new JoinRecordS3(); | ||
|
||
export async function saveJoinRecordToS3( | ||
submission: JoinRecord, | ||
key: string = "", | ||
) { | ||
return joinRecordS3.save(submission, key); | ||
} | ||
|
||
export async function getJoinRecordFromS3(key: string) { | ||
return joinRecordS3.get(key); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { JoinFormValues } from "@/components/JoinForm/JoinForm"; | ||
|
||
type JoinRecord = JoinFormValues & { | ||
submission_time: string; | ||
code: number | null; | ||
replayed: number; | ||
install_number: number | null; | ||
}; | ||
|
||
export type { JoinRecord }; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Can we set up some kind of datadog alert for this at least?
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.
We can definitely emit a metric. TBH I was trying to avoid setting up metrics for as long as possible 😂