Publish ಎರಡು ಬಾರಿ ಒತ್ತಿದರೆ ಈಗ ಒಮ್ಮೆ ಮಾತ್ರ ಪ್ರಕಟವಾಗುತ್ತದೆ
ಒಂದೇ ಆ್ಯಪ್ಗಾಗಿ ಮೂರು ಪ್ರಕಟಣಾ ವಿನಂತಿಗಳು ನಮ್ಮ API ಗೆ 84 ಮಿಲಿಸೆಕೆಂಡ್ ಅಂತರದಲ್ಲಿ ತಲುಪಿದವು, ಮತ್ತು ಪ್ರತಿಯೊಂದೂ ಆ ಆ್ಯಪ್ನ ಪೂರ್ಣ ಡೆಪ್ಲಾಯ್ ಆರಂಭಿಸಿತು. ಅವು ಒಂದೇ ಹೋಸ್ಟಿಂಗ್ನಲ್ಲಿ ಒಂದಕ್ಕೊಂದು ಸ್ಪರ್ಧಿಸಿದವು, ಮತ್ತು ಪರಿಣಾಮವಾಗಿ ಹಲವು ಬಿಡುಗಡೆಗಳು ವಿಫಲವಾದವು ಏಕೆಂದರೆ ಇನ್ನೊಂದು ಮೊದಲೇ ತಲುಪಿತ್ತು. ಗೋಚರ ಸೂಚನೆ ಕೇವಲ “release failed” ಇಮೇಲ್ ಆಗಿತ್ತು — ಆ್ಯಪ್ ಸ್ವತಃ ಸರಿಯಾಗಿಯೇ ಕೊನೆಗೊಂಡಿತ್ತು. ಈಗ ಒಂದು ಆ್ಯಪ್ಗಾಗಿ ಇನ್ನೊಂದು ಪ್ರಕಟಣೆ ನಡೆಯುತ್ತಿರುವಾಗ ಬರುವ ಪ್ರಕಟಣೆ ಎರಡನೇ ಬಿಲ್ಡ್ ಆರಂಭಿಸುವುದಿಲ್ಲ. ಯಾವ ವಿನಂತಿ ಗೆಲ್ಲುತ್ತದೆ ಎಂದು ಡೇಟಾಬೇಸ್ ನಿರ್ಧರಿಸುತ್ತದೆ, ಮತ್ತು ಉಳಿದವರಿಗೆ ಸತ್ಯ ಹೇಳಲಾಗುತ್ತದೆ: ಒಂದು ಪ್ರಕಟಣೆ ಈಗಾಗಲೇ ನಡೆಯುತ್ತಿದೆ.
ಏನಾಯಿತು
Mythex ನಲ್ಲಿ ಆ್ಯಪ್ ಪ್ರಕಟಿಸಿದಾಗ, API ಆ್ಯಪ್ಗಾಗಿ ಒಂದು ಡೆಪ್ಲಾಯ್ ದಾಖಲೆ ರಚಿಸುತ್ತದೆ ಮತ್ತು ನಮ್ಮ ಆರ್ಕೆಸ್ಟ್ರೇಟರ್ ಅನ್ನು — ಬಿಲ್ಡ್ಗಳನ್ನು ನಡೆಸುವ ಸೇವೆ — ಆ್ಯಪ್ ಬಿಲ್ಡ್ ಮಾಡಿ ಬಿಡುಗಡೆ ಮಾಡಲು ಕೇಳುತ್ತದೆ. ಪ್ರಕಟಣೆ Publish ಬಟನ್ನಿಂದ, ಇನ್ನೊಂದು ಬ್ರೌಸರ್ ಟ್ಯಾಬ್ನಿಂದ, ಅಥವಾ ನೀವು ಕೇಳಿದಾಗ ಏಜೆಂಟ್ನಿಂದ ಆರಂಭವಾಗಬಹುದು. ಡಬಲ್ ಕ್ಲಿಕ್, ಎರಡು ಟ್ಯಾಬ್ಗಳು, ಅಥವಾ ಎರಡು ಬಾರಿ ಬಂದ ಏಜೆಂಟ್ ವಿನಂತಿ — ಇವೆಲ್ಲವೂ ಒಂದೇ ಆ್ಯಪ್ಗೆ ಬಹು ಪ್ರಕಟಣೆಗಳನ್ನು ಬಹುತೇಕ ಒಂದೇ ಕ್ಷಣದಲ್ಲಿ ಉಂಟುಮಾಡಬಹುದು.
ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಮೂರು 84 ms ಒಳಗೆ ಬಂದವು. ಪ್ರತಿಯೊಂದೂ ಪೂರ್ಣ ಡೆಪ್ಲಾಯ್ ನಡೆಸಿತು. ಹೋಸ್ಟಿಂಗ್ ವೇದಿಕೆಯಲ್ಲಿ ಅದೇ ಆ್ಯಪ್ನ ಬಿಡುಗಡೆಗಳು ಒಂದೇ ಸೆಕೆಂಡಿನಲ್ಲಿ ರಚನೆಯಾದವು, ಮತ್ತು ಇತರವು ಈಗಾಗಲೇ ನಡೆಯುತ್ತಿದ್ದ ಕಾರಣ ಅವುಗಳಲ್ಲಿ ಮೂರು ವಿಫಲವಾದವು. ನಂತರದ ಒಂದು ಬಿಡುಗಡೆ ಸಿಲುಕಿಕೊಂಡಿತು, ಮತ್ತು ನಂತರ ಆ್ಯಪ್ ಕೆಲಸ ಮಾಡಿತು.
ಅದೇ ಇದನ್ನು ಗಮನಿಸದಂತೆ ಮಾಡಿತು. ಬಳಕೆದಾರರು ಒಂದು ಕೆಲಸ ಮಾಡುವ ಆ್ಯಪ್ ನೋಡಿದರು. ವೈಫಲ್ಯಗಳು ಕೇವಲ ಬಿಡುಗಡೆ-ವಿಫಲ ಇಮೇಲ್ಗಳಲ್ಲಿ ಕಾಣಿಸಿಕೊಂಡವು.
ಏನೂ ಏಕೆ ತಡೆಯಲಿಲ್ಲ
ಪ್ರಕಟಣಾ ಕೋಡ್ನಲ್ಲಿ ಪ್ರಗತಿಯಲ್ಲಿರುವ ಡೆಪ್ಲಾಯ್ಗಳನ್ನು ನೋಡುವ ಒಂದು ಹಂತ ಇತ್ತು. ಆದರೆ ಅದು ಮಾಡುತ್ತಿದ್ದದ್ದು ಪ್ರಾರಂಭಿಸುವ ಮೊದಲು ಪ್ರಗತಿಯಲ್ಲಿರುವ ಪ್ರತಿ ಡೆಪ್ಲಾಯ್ ಅನ್ನು “ವಿಫಲ” ಎಂದು ಗುರುತಿಸುವುದು — “ಹೊಸ ಪ್ರಕಟಣೆಯಿಂದ ಬದಲಾಯಿಸಲ್ಪಟ್ಟಿದೆ”. ಅದು ಕ್ರ್ಯಾಶ್ ಆದ ಪ್ರಕ್ರಿಯೆ ಬಿಟ್ಟುಹೋದ ಬಿಲ್ಡ್ಗಳನ್ನು ಶುಚಿಗೊಳಿಸಲು ಉದ್ದೇಶಿಸಲಾಗಿತ್ತು.
ವಾಸ್ತವದಲ್ಲಿ, ಬಿಲ್ಡ್ ಮಧ್ಯದಲ್ಲಿ ಬಂದ ಎರಡನೇ ಪ್ರಕಟಣೆ ಮೊದಲನೆಯದನ್ನು ಸತ್ತಿದೆ ಎಂದು ಘೋಷಿಸಿ ತನ್ನದೇ ಬಿಲ್ಡ್ ಆರಂಭಿಸುತ್ತಿತ್ತು. ಎರಡೂ ಒಂದೇ ಆ್ಯಪ್ಗೆ ಪೂರ್ಣಗೊಳ್ಳುವವರೆಗೆ ನಡೆದವು. ಯಾವುದೇ ಲಾಕ್ ಇರಲಿಲ್ಲ; ಬದಲಿಗೆ ಸ್ಪರ್ಧೆಗೆ ದಾರಿ ತೆರೆಯುವ ಹಂತವಿತ್ತು.
ಆ್ಯಪ್ನ ಮೊದಲ ಪ್ರಕಟಣೆಗೆ ಇನ್ನೊಂದು, ವಿಚಿತ್ರ ಲಕ್ಷಣವೂ ಇತ್ತು. ಮರುಬಳಸಲು ಇನ್ನೂ ಡೆಪ್ಲಾಯ್ ದಾಖಲೆ ಇಲ್ಲದ ಕಾರಣ, ಎರಡು ಏಕಕಾಲೀನ ಮೊದಲ ಪ್ರಕಟಣೆಗಳು ಒಂದನ್ನೇ ಸೇರಿಸಲು ಪ್ರಯತ್ನಿಸಿದವು. ಡೇಟಾಬೇಸ್ನಲ್ಲಿ ಆ್ಯಪ್ನ ಲಿಂಕ್ ಹೆಸರಿನ (ಅದರ slug, ಉದಾಹರಣೆಗೆ your-app.mythex.ai ನಲ್ಲಿ your-app) ಮೇಲೆ ಒಂದು ಅನನ್ಯ ಇಂಡೆಕ್ಸ್ ಇದೆ, ಆದ್ದರಿಂದ ಎರಡನೇ ಸೇರಿಸುವಿಕೆ ವಿಫಲವಾಯಿತು. API ಅದನ್ನು “ಆ ಲಿಂಕ್ ಹೆಸರು ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ” ಎಂದು ಅನುವಾದಿಸಿತು — ಆ ಕ್ಷಣದಲ್ಲಿ ಆ ಹೆಸರಿನಲ್ಲಿ ಯಶಸ್ವಿಯಾಗಿ ಪ್ರಕಟವಾಗುತ್ತಿದ್ದ ಆ್ಯಪ್ ಅನ್ನು ಮರುಹೆಸರಿಸಲು ಬಳಕೆದಾರರಿಗೆ ಸಲಹೆ ನೀಡುತ್ತಾ.
ಪರಿಹಾರ: ಕ್ಲೈಮ್ ಅದೇ ಲಾಕ್
ಈಗ ಡೆಪ್ಲಾಯ್ ದಾಖಲೆಯನ್ನು ಕ್ಲೈಮ್ ಮಾಡುವುದು ಒಂದೇ ಷರತ್ತುಬದ್ಧ ಡೇಟಾಬೇಸ್ ಅಪ್ಡೇಟ್: ಈ ಸಾಲನ್ನು ತೆಗೆದುಕೊಂಡು ಅದನ್ನು ಬಿಲ್ಡಿಂಗ್ ಎಂದು ಗುರುತಿಸಿ ಯಾರೂ ಪ್ರಕಟಿಸದಿದ್ದರೆ ಮಾತ್ರ. ಇದು ಒಂದೇ ಸ್ಟೇಟ್ಮೆಂಟ್ ಆಗಿರುವುದರಿಂದ, ಒಂದೇ ಮಿಲಿಸೆಕೆಂಡಿನಲ್ಲಿ ಬರುವ ವಿನಂತಿಗಳನ್ನು ಡೇಟಾಬೇಸ್ ಇತ್ಯರ್ಥಪಡಿಸುತ್ತದೆ. ಅವುಗಳಲ್ಲಿ ಒಂದು ಮಾತ್ರ ಸಾಲನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ. ಉಳಿದವು ಶೂನ್ಯ ಸಾಲುಗಳು ಬದಲಾದವು ಎಂದು ನೋಡಿ ನಿಲ್ಲುತ್ತವೆ ಮತ್ತು ಆರ್ಕೆಸ್ಟ್ರೇಟರ್ ತಲುಪುವುದಿಲ್ಲ.
ಲಾಕ್ಗೆ ತನ್ನ ಹೊಂದಿರುವವನು ಸತ್ತಾಗ ಹೊರಬರುವ ದಾರಿಯೂ ಬೇಕು. ಪ್ರಕಟಣೆಯ ಮಧ್ಯದಲ್ಲಿ API ಮರುಪ್ರಾರಂಭಗೊಂಡರೆ, ಸಾಲು “building” ಎಂದೇ ಶಾಶ್ವತವಾಗಿ ಉಳಿಯುತ್ತಿತ್ತು ಮತ್ತು ಆ್ಯಪ್ ಪ್ರಕಟಿಸಲಾಗದಾಗುತ್ತಿತ್ತು. ಆದ್ದರಿಂದ ಮಾಲೀಕರು ಹೃದಯ ಬಡಿತ (heartbeat) ಕಳುಹಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿದ ಸಾಲನ್ನು — ನಡೆಯುತ್ತಿರುವ ಪ್ರಕಟಣೆ ಪ್ರತಿ 30 ಸೆಕೆಂಡಿಗೊಮ್ಮೆ ಸಾಲನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡುತ್ತದೆ, ಮತ್ತು ಐದು ನಿಮಿಷಗಳ ಮೌನ ಸತ್ತಿದೆ ಎಂದು ಎಣಿಸಲ್ಪಡುತ್ತದೆ — ಮರು-ಕ್ಲೈಮ್ ಮಾಡಬಹುದು. ಆ ಮಿತಿ ಹೃದಯ ಬಡಿತದಿಂದ ಬರುತ್ತದೆ, ಬಿಲ್ಡ್ ಎಷ್ಟು ಸಮಯ ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ ಎಂಬ ಊಹೆಯಿಂದಲ್ಲ. ಬಳಕೆದಾರರ ಸ್ವಂತ Dockerfile ಅನ್ನು ಬಿಲ್ಡ್ ಮಾಡುವುದು ಕಾನೂನುಬದ್ಧವಾಗಿ ಬಹಳ ಸಮಯ ತೆಗೆದುಕೊಳ್ಳಬಹುದು, ಮತ್ತು ಇನ್ನೂ ಹೃದಯ ಬಡಿತ ಕಳುಹಿಸುವ ನಿಧಾನ ಬಿಲ್ಡ್ ತನ್ನ ಕ್ಲೈಮ್ ಅನ್ನು ಉಳಿಸಿಕೊಳ್ಳುತ್ತದೆ.
ಪ್ರಕಟಣೆಯ ಮೊದಲು ಪ್ರಗತಿಯಲ್ಲಿರುವ ಪ್ರತಿ ಡೆಪ್ಲಾಯ್ ಅನ್ನು ವಿಫಲಗೊಳಿಸುತ್ತಿದ್ದ ಹಂತ ಈಗ ಚಾಲನೆಯಾಗುವುದಿಲ್ಲ. ಸತ್ತ ಪ್ರಕ್ರಿಯೆ ಬಿಟ್ಟುಹೋದ ಸಾಲುಗಳನ್ನು ಮಾತ್ರ ಶುಚಿಗೊಳಿಸಲಾಗುತ್ತದೆ.
ಸೋತವರಿಗೆ ಸತ್ಯ ಹೇಳುವುದು
ಸೋತ ವಿನಂತಿಗೆ ಈಗ ಸ್ಪಷ್ಟ ಉತ್ತರ ಸಿಗುತ್ತದೆ: publish_in_progress, ಜೊತೆಗೆ ಚಾಲನೆಯಲ್ಲಿರುವ ಡೆಪ್ಲಾಯ್ನ ID. ಪ್ರಕಟಣೆ ಆರಂಭಿಸಬಹುದಾದ ಪ್ರತಿ ಸ್ಥಳವೂ ಇದನ್ನು ನಿಭಾಯಿಸುತ್ತದೆ:
- ವರ್ಕ್ಸ್ಪೇಸ್ ಈಗಾಗಲೇ ನಡೆಯುತ್ತಿರುವ ಬಿಲ್ಡ್ ಅನ್ನು ಅನುಸರಿಸುತ್ತದೆ, ಅದರ ಮೇಲೆ ದೋಷ ತೋರಿಸುವ ಬದಲು.
- ಏಜೆಂಟ್ಗೆ ಈ ಆ್ಯಪ್ನ ಪ್ರಕಟಣೆ ಈಗಾಗಲೇ ನಡೆಯುತ್ತಿದೆ ಮತ್ತು ಅದಕ್ಕಾಗಿ ಕಾಯಲು ಹೇಳಲಾಗುತ್ತದೆ, ಏನೋ ವಿಫಲವಾಗಿದೆ ಎಂದು ಹೇಳುವ ಬದಲು — ಹಿಂದೆ ಅದು ಅದನ್ನು “ಸರಿಪಡಿಸಲು” Dockerfile ಬದಲಿಸಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸುವಂತೆ ಮಾಡಬಹುದಿತ್ತು.
- ಮೊದಲ ಪ್ರಕಟಣೆಯ ಲಿಂಕ್ ಹೆಸರಿನ ಘರ್ಷಣೆ ಪರಿಶೀಲಿಸಲಾಗುತ್ತದೆ: ಹೆಸರನ್ನು ಹೊಂದಿರುವ ಸಾಲು ಈ ಪ್ರಾಜೆಕ್ಟ್ನ ಸ್ವಂತ ನಡೆಯುತ್ತಿರುವ ಪ್ರಕಟಣೆಯಾಗಿದ್ದರೆ, ಉತ್ತರ “ಈಗಾಗಲೇ ಪ್ರಕಟವಾಗುತ್ತಿದೆ”, “ಆ ಹೆಸರು ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ” ಅಲ್ಲ. ಇನ್ನೊಂದು ಪ್ರಾಜೆಕ್ಟ್ನೊಂದಿಗಿನ ನಿಜವಾದ ಘರ್ಷಣೆಗೆ ಇನ್ನೂ ಮರುಹೆಸರಿಸುವ ಸಂದೇಶ ಸಿಗುತ್ತದೆ.
ನಾವು ಇದನ್ನು ಹೇಗೆ ಪರಿಶೀಲಿಸಿದೆವು
ನಾವು ನಿಜವಾದ ಡೇಟಾಬೇಸ್ ಮತ್ತು ಸ್ಟಬ್ ಆರ್ಕೆಸ್ಟ್ರೇಟರ್ ವಿರುದ್ಧ ಒಂದೇ ಆ್ಯಪ್ಗೆ ಮೂರು ಪ್ರಕಟಣೆಗಳನ್ನು ಏಕಕಾಲದಲ್ಲಿ ನಡೆಸಿ, ಆರ್ಕೆಸ್ಟ್ರೇಟರ್ನಿಂದ ಎಷ್ಟು ಡೆಪ್ಲಾಯ್ಗಳನ್ನು ಕೇಳಲಾಗಿದೆ ಎಂದು ಎಣಿಸುವ ಮರುಸೃಷ್ಟಿ ಸ್ಕ್ರಿಪ್ಟ್ ಬರೆದೆವು. ಇದು ಮೊದಲ ಪ್ರಕಟಣೆ ಮತ್ತು ಲೈವ್ ಆ್ಯಪ್ನ ಮರುಪ್ರಕಟಣೆ ಎರಡನ್ನೂ ಒಳಗೊಂಡಿದೆ. ಪರಿಹಾರದ ಮೊದಲು, ಅದು ಎರಡು ಡೆಪ್ಲಾಯ್ಗಳನ್ನು ಎಣಿಸಿತು. ನಂತರ, ಒಂದು.
ಸ್ಕ್ರಿಪ್ಟ್ ತಪ್ಪಿಸಿಕೊಳ್ಳುವ ದಾರಿಯನ್ನೂ ಒಳಗೊಂಡಿದೆ: ಅದು ಆ್ಯಪ್ನ ಸಾಲನ್ನು ಹತ್ತು ನಿಮಿಷಗಳ ಕಾಲ ಹೃದಯ ಬಡಿತವಿಲ್ಲದೆ ಬಿಲ್ಡಿಂಗ್ ಎಂದು ಗುರುತಿಸುತ್ತದೆ, ಮತ್ತೆ ಪ್ರಕಟಿಸುತ್ತದೆ, ಮತ್ತು ಹೊಸ ಪ್ರಕಟಣೆ ಸಾಲನ್ನು ಕ್ಲೈಮ್ ಮಾಡಿ ಚಲಿಸುತ್ತದೆ ಎಂದು ಪರಿಶೀಲಿಸುತ್ತದೆ.
ಯುನಿಟ್ ಪರೀಕ್ಷೆಗಳು ಲಾಕ್ ಹೊಂದಬೇಕಾದ ಎರಡು ವಿಷಯಗಳನ್ನು ಪರಿಶೀಲಿಸುತ್ತವೆ: ಏಕಕಾಲದ ಮೂರು ಮರುಪ್ರಕಟಣೆಗಳಲ್ಲಿ ನಿಖರವಾಗಿ ಒಂದು ಮಾತ್ರ ಹಾದುಹೋಗುತ್ತದೆ ಮತ್ತು ಉಳಿದ ಎರಡಕ್ಕೆ ಪ್ರಕಟಣೆ ನಡೆಯುತ್ತಿದೆ ಎಂದು ಹೇಳಲಾಗುತ್ತದೆ; ಮತ್ತು ಮಾಲೀಕ ಸತ್ತ ಬಿಲ್ಡ್ ಅನ್ನು ಕ್ಲೈಮ್ ಮಾಡಬಹುದು. ಇನ್ನೊಂದು ಪರೀಕ್ಷೆ ಹೊಸ ಪ್ರಯತ್ನವು ಹಿಂದಿನ ಪ್ರಯತ್ನದ ದೋಷ ಸಂದೇಶವನ್ನು ಸಾಗಿಸುವುದಿಲ್ಲ ಎಂದು ಪರಿಶೀಲಿಸುತ್ತದೆ.
ನಾವು ಇದರಿಂದ ಕಲಿತದ್ದು
- ಶುಚಿಗೊಳಿಸುವ ಕೋಡ್ ವೇಷ ಹಾಕಿದ ಸ್ಪರ್ಧೆಯಾಗಿರಬಹುದು. “ಪ್ರಗತಿಯಲ್ಲಿರುವ ಎಲ್ಲವನ್ನೂ ವಿಫಲಗೊಳಿಸಿ, ನಂತರ ಆರಂಭಿಸಿ” ಎಂಬುದು ಸ್ವಚ್ಛತೆಯಂತೆ ಕಾಣುತ್ತದೆ. ಎರಡು ಕರೆಗಾರರೊಂದಿಗೆ, ಅದು ಪರಸ್ಪರ ರದ್ದುಗೊಳಿಸುವುದು.
- ಡೇಟಾಬೇಸ್ಗೆ ತೀರ್ಪು ನೀಡಲು ಬಿಡಿ. ಓದು ನಂತರ ಬರೆಯುವುದು ಇನ್ನೊಂದು ವಿನಂತಿಗೆ ಅಂತರವನ್ನು ಬಿಡುತ್ತದೆ. ಒಂದೇ ಷರತ್ತುಬದ್ಧ ಅಪ್ಡೇಟ್ ಬಿಡುವುದಿಲ್ಲ.
- ಪ್ರತಿ ಲಾಕ್ಗೂ ಜೀವಂತಿಕೆಗೆ ಜೋಡಿಸಿದ ಅವಧಿ ಮುಕ್ತಾಯ ಬೇಕು. ಇಲ್ಲದಿದ್ದರೆ, ಕ್ರ್ಯಾಶ್ ಸಿಲುಕಿದ ಆ್ಯಪ್ ಆಗುತ್ತದೆ.
- ದೋಷ ಸಂದೇಶಗಳು ಸೂಚನೆಗಳು. “ಆ ಹೆಸರು ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ” ಜನರಿಗೆ ತಪ್ಪು ಕೆಲಸ ಮಾಡುವಂತೆ ಹೇಳಿತು. ಸರಿಯಾದ ಸಂದೇಶ ಸರಳ ಮತ್ತು ನಿಜವಾಗಿತ್ತು.
ಡಾಕ್ಸ್ನಲ್ಲಿ ಪ್ರಕಟಣೆಯ ಬಗ್ಗೆ ಇನ್ನಷ್ಟು: how to publish. ಮತ್ತು ಸಂಬಂಧಿತ ಪರಿಹಾರ: your published app stays up while you republish it.