Skip to content

fallback session state to file #526

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

Merged
merged 5 commits into from
Nov 21, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
change to use storage path
Signed-off-by: shmck <shawn.j.mckay@gmail.com>
  • Loading branch information
ShMcK committed Nov 21, 2021
commit 63c80671b03241742e3d45e7fdb9597cb2ebf01b
2 changes: 1 addition & 1 deletion src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ export const CONTENT_SECURITY_POLICY_EXEMPTIONS: string | null =
export const WEBHOOK_TOKEN = process.env.CODEROAD_WEBHOOK_TOKEN || null

// a path to write session state to a file. Useful for maintaining session across containers
export const SESSION_FILE_PATH = process.env.CODEROAD_SESSION_FILE_PATH || null
export const SESSION_STORAGE_PATH = process.env.CODEROAD_STORAGE_PATH || null
1 change: 1 addition & 0 deletions src/services/context/state/Position.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Position {
setTutorial(workspaceState: vscode.Memento, tutorial: TT.Tutorial): void {
this.storage = new Storage<T.Position>({
key: `coderoad:position:${tutorial.id}:${tutorial.version}`,
filePath: 'coderoad_position',
storage: workspaceState,
defaultValue,
})
Expand Down
1 change: 1 addition & 0 deletions src/services/context/state/Tutorial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class Tutorial {
constructor(workspaceState: vscode.Memento) {
this.storage = new Storage<TT.Tutorial | null>({
key: 'coderoad:currentTutorial',
filePath: 'coderoad_tutorial',
storage: workspaceState,
defaultValue: null,
})
Expand Down
4 changes: 2 additions & 2 deletions src/services/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ export const removeFile = (...paths: string[]) => {
export const readFile = (...paths: string[]): Promise<string | void> => {
const filePath = getWorkspacePath(...paths)
return asyncReadFile(getWorkspacePath(...paths), 'utf8').catch((err) => {
console.warn(`Failed to read from ${filePath}`)
console.warn(`Failed to read from ${filePath}: ${err.message}`)
})
}

export const writeFile = (data: any, ...paths: string[]): Promise<void> => {
const filePath = getWorkspacePath(...paths)
return asyncWriteFile(filePath, JSON.stringify(data)).catch((err) => {
console.warn(`Failed to write to ${filePath}`)
console.warn(`Failed to write to ${filePath}: ${err.message}`)
})
}
40 changes: 25 additions & 15 deletions src/services/storage/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as vscode from 'vscode'
import { readFile, writeFile } from '../node'
import { SESSION_FILE_PATH } from '../../environment'
import { SESSION_STORAGE_PATH } from '../../environment'

// NOTE: localStorage is not available on client
// and must be stored in editor
Expand All @@ -10,37 +10,47 @@ import { SESSION_FILE_PATH } from '../../environment'
// forcing it to be passed in through activation and down to other tools
class Storage<T> {
private key: string
private filePath: string
private storage: vscode.Memento
private defaultValue: T
constructor({ key, storage, defaultValue }: { key: string; storage: vscode.Memento; defaultValue: T }) {
constructor({
key,
filePath,
storage,
defaultValue,
}: {
key: string
filePath: string
storage: vscode.Memento
defaultValue: T
}) {
this.storage = storage
this.key = key
this.filePath = filePath
this.defaultValue = defaultValue
}
public get = async (): Promise<T> => {
const value: string | undefined = await this.storage.get(this.key)
if (value) {
return JSON.parse(value)
} else if (SESSION_FILE_PATH) {
} else if (SESSION_STORAGE_PATH) {
try {
// optionally read from file as a fallback to local storage
const sessionFile = await readFile(SESSION_FILE_PATH)
const sessionFile = await readFile(SESSION_STORAGE_PATH, `${this.filePath}.json`)
if (!sessionFile) {
throw new Error('No session file found')
}
const session = JSON.parse(sessionFile)
const data: T = JSON.parse(sessionFile)

if (session) {
const keys = Object.keys(session)
if (data) {
// validate session
const keys = Object.keys(data)
if (keys.length) {
// should only be one
this.key = keys[0]
return session[this.key]
return data
}
}
} catch (err) {
console.warn(`Failed to read or parse session file: ${SESSION_FILE_PATH}`)
console.warn(`Failed to read or parse session file: ${SESSION_STORAGE_PATH}/${this.filePath}.json`)
}
}
return this.defaultValue
Expand All @@ -61,12 +71,12 @@ class Storage<T> {
this.writeToSessionFile(next)
}
public writeToSessionFile(data: string) {
// optionally write to file
if (SESSION_FILE_PATH) {
// optionally write state to file, useful when state cannot be controlled across containers
if (SESSION_STORAGE_PATH) {
try {
writeFile({ [this.key]: data }, SESSION_FILE_PATH)
writeFile(data, SESSION_STORAGE_PATH, `${this.filePath}.json`)
} catch (err: any) {
console.warn(`Failed to write coderoad session to path: ${SESSION_FILE_PATH}`)
console.warn(`Failed to write coderoad session to path: ${SESSION_STORAGE_PATH}/${this.filePath}.json`)
}
}
}
Expand Down