Enhance Schedule component by resetting time fields on cancel and draft mode toggle; improve session scheduling logic to prevent conflicts by adjusting start times if necessary.
This commit is contained in:
@@ -96,6 +96,9 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
|
||||
function handleClickCancel() {
|
||||
setDraftMode(false);
|
||||
setStartTime("");
|
||||
setEndTime("");
|
||||
setDuration(undefined);
|
||||
}
|
||||
|
||||
async function addSchesuledSession() {
|
||||
@@ -129,6 +132,9 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
function handleClickScheduleDemo() {
|
||||
setDateForInstantStart(undefined);
|
||||
setStartAt(new Date());
|
||||
setStartTime("");
|
||||
setEndTime("");
|
||||
setDuration(undefined);
|
||||
setDraftMode(true);
|
||||
}
|
||||
|
||||
@@ -184,9 +190,12 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
|
||||
useEffect(() => {
|
||||
function handleEscKey(e: KeyboardEvent) {
|
||||
if (!draftMode && e.key !== "Escape") return;
|
||||
if (!draftMode || e.key !== "Escape") return;
|
||||
|
||||
setDraftMode(false);
|
||||
setStartTime("");
|
||||
setEndTime("");
|
||||
setDuration(undefined);
|
||||
}
|
||||
|
||||
document.addEventListener("keyup", handleEscKey, false);
|
||||
@@ -194,7 +203,7 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
return () => {
|
||||
document.removeEventListener("keyup", handleEscKey, false);
|
||||
};
|
||||
}, []);
|
||||
}, [draftMode]);
|
||||
|
||||
return (
|
||||
<div className="relative h-screen overflow-y-auto bg-[#F2F2F2] text-sm">
|
||||
|
||||
@@ -4,6 +4,7 @@ import Build from "../models/Build.js";
|
||||
import Schedule from "../models/Schedule.js";
|
||||
import {
|
||||
addMinutes,
|
||||
addSeconds,
|
||||
areIntervalsOverlapping,
|
||||
endOfDay,
|
||||
isValid,
|
||||
@@ -78,7 +79,7 @@ router.get("/:buildId", async (req, res) => {
|
||||
router.post("/", async (req, res) => {
|
||||
const { companyId, buildId, slot, startAt, client, duration } = req.body;
|
||||
|
||||
const startAtISO = parseISO(startAt);
|
||||
let startAtISO = parseISO(startAt);
|
||||
|
||||
if (!isValid(startAtISO)) {
|
||||
return res.status(400).json({
|
||||
@@ -96,9 +97,50 @@ router.post("/", async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
// Check for conflicts at the same minute and adjust time if needed
|
||||
// This prevents multiple sessions from starting simultaneously on the same server
|
||||
// We check all sessions regardless of company, build, or slot to prevent server conflicts
|
||||
let adjustedStartAt = startAtISO;
|
||||
let maxAttempts = 100; // Prevent infinite loop
|
||||
let attempts = 0;
|
||||
|
||||
while (attempts < maxAttempts) {
|
||||
// Find sessions starting within 10 seconds of our target time
|
||||
// This ensures sessions don't start simultaneously on the same session server
|
||||
const conflictingSessions = await ScheduledSession.find({
|
||||
startAt: {
|
||||
$gte: adjustedStartAt,
|
||||
$lt: addSeconds(adjustedStartAt, 10),
|
||||
},
|
||||
});
|
||||
|
||||
if (conflictingSessions.length === 0) {
|
||||
// No conflict found, use this time
|
||||
break;
|
||||
}
|
||||
|
||||
// Find the latest conflicting session and schedule after it
|
||||
// This gives the first build time to start and fill video memory
|
||||
// so the second build will start on another server with more available memory
|
||||
const latestSession = conflictingSessions.reduce((latest, session) =>
|
||||
new Date(session.startAt) > new Date(latest.startAt) ? session : latest
|
||||
);
|
||||
|
||||
adjustedStartAt = addSeconds(new Date(latestSession.startAt), 10);
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (attempts >= maxAttempts) {
|
||||
return res.status(400).json({
|
||||
status: "error",
|
||||
message: "Не удалось найти свободное время для планирования сеанса",
|
||||
});
|
||||
}
|
||||
|
||||
startAtISO = adjustedStartAt;
|
||||
const endAtISO = addMinutes(startAtISO, duration);
|
||||
|
||||
// Check for overlapping sessions first
|
||||
// Check for overlapping sessions in the same slot
|
||||
const scheduledSessions = await ScheduledSession.find({
|
||||
companyId,
|
||||
buildId,
|
||||
|
||||
Reference in New Issue
Block a user