Skip to content

Commit

Permalink
fix bundle locking
Browse files Browse the repository at this point in the history
  • Loading branch information
CollinBeczak committed Nov 20, 2024
1 parent 8de728b commit 63d7cd8
Showing 1 changed file with 63 additions and 55 deletions.
118 changes: 63 additions & 55 deletions src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
startTask
} from '../../../services/Task/Task'

const LOCK_REFRESH_INTERVAL = 600000;
const LOCK_REFRESH_INTERVAL = 600000

/**
* WithTaskBundle passes down methods for creating new task bundles and
Expand All @@ -34,38 +34,41 @@ export function WithTaskBundle(WrappedComponent) {
loading: false,
}

refreshLockInterval = null;
refreshLockInterval = null

async componentDidMount() {
const { task } = this.props
if (_isFinite(_get(task, 'bundleId'))) {
await this.fetchBundle(task.bundleId)

Check warning on line 42 in src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx#L42

Added line #L42 was not covered by tests
}
this.updateBundlingConditions()

Check warning on line 44 in src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx#L44

Added line #L44 was not covered by tests
this.startLockRefresh()
}

async componentDidUpdate(prevProps, prevState) {
async componentDidUpdate(prevProps) {
const { task } = this.props
const { taskBundle } = this.state
const { taskBundle: prevTaskBundle } = prevState

if (_get(task, 'id') !== _get(prevProps, 'task.id')) {
if (this.state.taskBundle) {
this.unlockTasks(this.state.taskBundle, null)

Check warning on line 52 in src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx#L51-L52

Added lines #L51 - L52 were not covered by tests
}

this.setState({ selectedTasks: [], taskBundle: null, initialBundle: null, loading: false, errorMessage: null })
if (_isFinite(_get(task, 'bundleId'))) {
await this.fetchBundle(task.bundleId)

Check warning on line 57 in src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx#L55-L57

Added lines #L55 - L57 were not covered by tests
}
this.updateBundlingConditions()

Check warning on line 59 in src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx#L59

Added line #L59 was not covered by tests
}
if (taskBundle !== prevTaskBundle) {
this.startLockRefresh()
}
}

componentWillUnmount() {
this.stopLockRefresh()
if (this.state.taskBundle) {
this.unlockTasks(this.state.taskBundle, null)
}

Check warning on line 67 in src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/HOCs/WithTaskBundle/WithTaskBundle.jsx#L64-L67

Added lines #L64 - L67 were not covered by tests
}

startLockRefresh = () => {
this.stopLockRefresh()
this.refreshLockInterval = setInterval(() => {
const { taskBundle } = this.state
if (taskBundle) {
Expand All @@ -92,6 +95,7 @@ export function WithTaskBundle(WrappedComponent) {
selectedTasks: taskBundle?.taskIds || [],
bundleEditsDisabled: this.updateBundlingConditions()
})
this.startLockRefresh()
} catch (error) {
console.error("Error fetching bundle:", error)
this.setState({ errorMessage: "Failed to fetch task bundle. Please try again." })
Expand Down Expand Up @@ -133,39 +137,56 @@ export function WithTaskBundle(WrappedComponent) {
}
}

unlockTasks = async (taskBundle,initialBundle) => {
const tasksToUnlock = taskBundle.taskIds
if(initialBundle){
tasksToUnlock.filter(taskId => !initialBundle.taskIds.includes(taskId))
}
await Promise.all(tasksToUnlock.map(taskId =>
this.props.releaseTask(taskId).then(() => {
setTimeout(() => localStorage.removeItem(`lock-${taskId}`), 1500)
}).catch(console.error)
unlockTasks = async (taskBundle, initialBundle) => {
const { task } = this.props
const tasksToUnlock = taskBundle.taskIds.filter(taskId =>
!initialBundle?.taskIds.includes(taskId) && taskId !== task.id
)

await Promise.all(tasksToUnlock.map(taskId =>
this.props.releaseTask(taskId).catch(console.error)
))
}

lockTask = async (taskId) => {
this.setState({ loading: true });
const { task } = this.props
if (task.id === taskId) {
return task
}

this.setState({ loading: true })
try {
const task = await this.props.startTask(taskId, true);
setTimeout(() => localStorage.removeItem(`lock-${taskId}`), 1500);
return task.entities.tasks[taskId];
const task = await this.props.startTask(taskId, true)
return task.entities.tasks[taskId]
} catch (error) {
console.error(`Failed to lock task ${taskId}:`, error);
this.setState({ errorMessage: `Failed to lock task ${taskId}. Please try again.` });
throw error;
console.error(`Failed to lock task ${taskId}:`, error)
this.setState({ errorMessage: `Failed to lock task ${taskId}. Please try again.` })
throw error
} finally {
this.setState({ loading: false });
this.setState({ loading: false })
}
}

clearActiveTaskBundle = async () => {
await this.unlockTasks()
this.setState({ selectedTasks: [], taskBundle: null })
createTaskBundle = async (taskIds, bundleTypeMismatch) => {
if (bundleTypeMismatch) {
throw new Error("Bundle type mismatch")
}

try {
const updatedTasks = await Promise.all(taskIds.map(this.lockTask))
this.setState({ taskBundle: { ...this.state.taskBundle, tasks: updatedTasks, taskIds } })
this.startLockRefresh()
} catch (error) {
console.error("Failed to create task bundle due to locking error:", error)
}
}

refreshTaskLock = async (taskId) => {
const { task } = this.props
if (task.id === taskId) {
return
}

try {
await this.props.refreshTaskLock(taskId)
} catch (error) {
Expand All @@ -174,20 +195,14 @@ export function WithTaskBundle(WrappedComponent) {
}
}

createTaskBundle = async (taskIds, bundleTypeMismatch) => {
if (bundleTypeMismatch) {
throw new Error("Bundle type mismatch")
}

try {
const updatedTasks = await Promise.all(taskIds.map(taskId =>
this.lockTask(taskId)
))

this.setState({ taskBundle: { ...this.state.taskBundle, tasks: updatedTasks, taskIds } })
} catch (error) {
console.error("Failed to create task bundle due to locking error:", error)
}
clearActiveTaskBundle = async () => {
const { taskBundle, initialBundle } = this.state
await this.unlockTasks(taskBundle, initialBundle)
this.setState({
selectedTasks: [],
taskBundle: null,
})
this.resetSelectedTasks()
}

resetTaskBundle = () => {
Expand All @@ -198,7 +213,7 @@ export function WithTaskBundle(WrappedComponent) {
}

removeTaskFromBundle = async (taskId) => {
const { taskBundle } = this.state
const { taskBundle, initialBundle } = this.state
if (taskBundle?.taskIds.length === 2) {
this.setState({ taskBundle: null })
return
Expand All @@ -207,19 +222,12 @@ export function WithTaskBundle(WrappedComponent) {
const updatedTaskIds = taskBundle.taskIds.filter(id => id !== taskId)
const updatedTasks = taskBundle.tasks.filter(task => task.id !== taskId)
const updatedTaskBundle = { ...taskBundle, taskIds: updatedTaskIds, tasks: updatedTasks }
await this.unlockTasks(updatedTaskBundle, taskBundle)

this.setState({ taskBundle: updatedTaskBundle })
}
if (initialBundle && !initialBundle.taskIds.includes(taskId)) {
await this.unlockTasks(updatedTaskBundle, taskBundle)
}

clearActiveTaskBundle = async () => {
const { taskBundle, initialBundle } = this.state
await this.unlockTasks(taskBundle, initialBundle)
this.setState({
selectedTasks: [],
taskBundle: null,
})
this.resetSelectedTasks()
this.setState({ taskBundle: updatedTaskBundle })
}

updateTaskBundle = async () => {
Expand Down

0 comments on commit 63d7cd8

Please sign in to comment.