ฟีดข่าวค้างสามวันทั้งที่งานรันครบ เพราะฟีดไม่ได้เรียงตามวันที่
งานที่ล้มแล้วขึ้นแดงยังพอไล่ได้ แต่งานที่รันครบ คืนค่าศูนย์ และรายงานว่าสำเร็จทุกชั้น ทั้งที่ผลลัพธ์นิ่งสนิทมาสามวัน อันนี้กว่าจะรู้ตัวคือมีคนมาทักว่าเว็บไม่มีข่าวใหม่
พอดีผมดูแลเว็บข่าวเฉพาะทางตัวหนึ่ง ที่ตามข่าวของแบรนด์ในอุตสาหกรรมเดียวกันประมาณยี่สิบกว่าราย แล้วเอามาขึ้นเป็นข่าวเด่นหน้าแรกทุกเช้า วันหนึ่งมีคนทักมาว่า "ไม่มีข่าวทุกวันเหรอ" ผมเปิดดูก็เจอว่าข่าวเด่นค้างอยู่ที่วันที่เดิมมาสามวันแล้ว ที่ทำเอาผมงงคือไปไล่ log ทุกขั้นตอน งานตามเวลารันครบทุกวัน คิวแปลทำครบ ตัวเผยแพร่พิมพ์ว่า RESULT OK ทุกครั้ง exit 0 หมด ไม่มี error สักบรรทัดเดียวในระบบทั้งเส้น สุดท้ายเป็นสามอย่างซ้อนกัน เลยเก็บมาเขียนไว้
ชื่อเว็บ ชื่อแบรนด์ ชื่อคำค้น และคีย์ทั้งหมดในบทความเป็นตัวอย่างที่ผมสมมติขึ้นแทนของจริง ส่วนโครงสร้าง ตัวเลขที่วัดได้ และโค้ดคือของจริงจากงานนั้น
สิ่งที่ทำให้เรื่องนี้ยืดยาวคือ ทุกชั้นในเส้นทางข้างบน ทำงานถูกตามที่มันถูกสั่งให้ทำจริงๆ ตัวรวมข่าวยิงคำค้นครบ ได้ผลกลับมา เขียนไฟล์สำเร็จ ขั้นแปลอ่านไฟล์แล้วไม่เจอรายการใหม่ก็เขียนกลับเท่าเดิม ตัวเผยแพร่อ่านรายการเดิม ยิงเข้า API สำเร็จ คืน exit 0
พูดง่ายๆ คือ ทุกชั้นตรวจว่าตัวเองทำงานเสร็จ ไม่มีชั้นไหนตรวจว่าผลลัพธ์เปลี่ยนไปจากเมื่อวานหรือเปล่า ผมเจอรูปแบบนี้ซ้ำหลายรอบในระบบอัตโนมัติ และทุกรอบมันเงียบเหมือนกันหมด
สคริปต์คืนค่าศูนย์แปลว่า "โค้ดวิ่งจนจบโดยไม่มีข้อยกเว้น" เท่านั้น มันไม่ได้แปลว่ามีของใหม่เข้าระบบ ระบบที่ผลลัพธ์เป็นสตรีมของข้อมูลสด ต้องมีการยืนยันคุณสมบัติของผลลัพธ์ต่างหาก ไม่ใช่ยืนยันแค่ว่าโปรแกรมรันจบ
กับดักที่หนึ่ง: RSS เรียงตามความเกี่ยวข้อง ไม่ใช่วันที่
ตัวรวมข่าวรุ่นแรกผมเขียนด้วย Node ดึง RSS ของบริการรวมข่าวมาแล้วตัดเอา 5 อันแรก ซึ่งดูสมเหตุสมผลมากถ้าคิดว่าฟีดเรียงใหม่สุดมาก่อน
// ก่อนแก้ — ตัดจากบนสุดตรงๆ โดยเดาว่าฟีดเรียงตามวันที่ให้แล้ว
function parseItems(xml, limit) {
return [...xml.matchAll(/<item>([\s\S]*?)<\/item>/g)]
.slice(0, limit) // <-- ต้นเหตุอยู่บรรทัดนี้
.map(m => readOne(m[1]));
}
ปัญหาคือฟีดตัวนั้น เรียงตามความเกี่ยวข้อง ไม่ใช่วันที่ ผมพิมพ์ลำดับที่ได้จริงออกมาดูวันหนึ่ง มันเรียงมาเป็น 2 ก.ย. แล้ว 6 ก.ย. แล้ว 3 ก.ย. คือสลับกันไปมา ข่าวของวันนี้มีอยู่จริงในฟีดเดียวกันนั่นแหละ แต่มันไปนอนอยู่ลำดับล่างๆ พอเราตัดเอาแค่ห้าอันแรก ก็ได้ชุดเดิมทุกวัน แล้วขั้นถัดไปที่กันซ้ำด้วย url ก็ข้ามทั้งหมด เพราะ ทุกลิงก์ที่ได้มาคือลิงก์ที่เคยเห็นแล้ว ฟีดหน้าเว็บเลยไม่ขยับ
ทางแก้คือแยกสองเรื่องออกจากกันให้ชัด: อ่านมาทั้งฟีดก่อน แล้วค่อยเรียงเอง แล้วค่อยตัด
// หลังแก้ — อ่านทุก item, เรียงตาม pubDate ที่แปลงเป็นเวลาจริง, แล้วค่อยตัด
function parseItems(xml, limit, must) {
const items = [...xml.matchAll(/<item>([\s\S]*?)<\/item>/g)].map(m => {
const b = m[1];
const get = re => { const x = b.match(re); return x ? decode(x[1]) : ''; };
const rawTitle = get(/<title>([\s\S]*?)<\/title>/);
const source = get(/<source[^>]*>([\s\S]*?)<\/source>/);
// พาดหัวของบริการนี้ลงท้ายด้วย " - <สำนักข่าว>" เสมอ ตัดทิ้งให้เหลือหัวข้อสะอาด
const title = source && rawTitle.endsWith(' - ' + source)
? rawTitle.slice(0, -(source.length + 3)) : rawTitle;
return { title, source, link: get(/<link>([\s\S]*?)<\/link>/),
pubDate: get(/<pubDate>([\s\S]*?)<\/pubDate>/) };
});
// แปลงเป็น epoch ก่อนเทียบ ถ้าแปลงไม่ได้ให้เป็น 0 (ตกไปท้ายแถว ไม่ใช่ขึ้นหัวแถว)
const ts = it => { const t = Date.parse(it.pubDate); return Number.isFinite(t) ? t : 0; };
return items.filter(hit(must)).sort((a, b) => ts(b) - ts(a)).slice(0, limit);
}
อีกตัวที่ผมปรับพร้อมกันคือหน้าต่างเวลาในคำค้น ของเดิมขอย้อนหลัง 45 วัน ซึ่งพอรวมกับการเรียงตามความเกี่ยวข้องแล้วมันคือสูตรของการได้ข่าวเก่าซ้ำๆ ผมลดเหลือ 10 วัน กองผู้สมัครเลยสดขึ้นชัดเจน
กับดักที่สอง: เรียงวันที่แบบสตริง เท่ากับเรียงตามชื่อวันในสัปดาห์
ตัวถัดไปในเส้นทางเขียนด้วย Python และมันก็เรียงวันที่เหมือนกัน แต่เรียงจาก pubDate ดิบที่เป็นรูปแบบ RFC-822 ตรงๆ
# รูปแบบที่ฟีดส่งมา — ขึ้นต้นด้วยชื่อวันในสัปดาห์เสมอ
"Tue, 08 Sep 2026 10:00:00 GMT"
"Fri, 04 Sep 2026 07:30:00 GMT"
"Mon, 07 Sep 2026 22:15:00 GMT"
# เรียงสตริงตรงๆ ได้ลำดับนี้ — เรียงตามตัวอักษรของ "ชื่อวัน" ไม่ใช่วันที่
# Fri < Mon < Sat < Sun < Thu < Tue < Wed
sorted(dates) # -> Fri 04 ก.ย. มาก่อน Mon 07 ก.ย. มาก่อน Tue 08 ก.ย.
นี่คือเหตุผลที่ข่าวใหม่สุดแพ้ข่าวอายุสัปดาห์หนึ่งได้เรื่อยๆ โดยไม่มีอะไรผิดพลาดให้เห็น ผมเลยเขียนฟังก์ชันดึงตัวเลขออกมาเรียงแทน
MON = {v: i for i, v in enumerate(
["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"], 1)}
def pubkey(it):
"""คีย์เรียงลำดับจาก pubDate แบบ RFC-822 ("Tue, 14 Jul 2026 10:00:00 GMT")
การเรียงสตริงดิบคือการเรียงตามชื่อวันในสัปดาห์ (Fri < Mon < Sat < Sun < Thu < Tue < Wed)
ซึ่งคือสาเหตุที่ข่าวใหม่สุดแพ้ข่าวเก่ามาตลอด"""
m = re.search(r"(\d{1,2})\s+(\w{3})\s+(\d{4})(?:\s+(\d{2}):(\d{2}))?",
it.get("pubDate", "") or "")
if not m:
return "" # ไม่มีวันที่ -> คีย์ว่าง -> ตกไปท้ายแถว
return "%s-%02d-%02d %s:%s" % (m.group(3), MON.get(m.group(2), 1), int(m.group(1)),
m.group(4) or "00", m.group(5) or "00")
ทุกครั้งที่โค้ดเรียงลำดับด้วยฟิลด์วันที่ที่ยังเป็นสตริงจากผู้ให้บริการภายนอก ให้ถือว่าผิดไว้ก่อน รูปแบบที่ขึ้นต้นด้วยชื่อวัน ชื่อเดือน หรือวันที่แบบ วัน/เดือน/ปี เรียงเป็นสตริงแล้วได้ผลที่ดูสมเหตุสมผลพอที่จะไม่มีใครสังเกต ให้แปลงเป็น epoch หรือรูปแบบ ปี-เดือน-วัน ที่เรียงได้จริงก่อนทุกครั้ง
กับดักที่สาม: ขอมาน้อย แล้วด่านกรองตีตกหมดตั้งแต่ยังไม่ทันได้ดู
พอย้ายไปใช้ API ของผู้ให้บริการข่าวอีกเจ้า ผมนึกว่าจะหมดเรื่องแล้ว เพราะเจ้านี้เรียงใหม่สุดมาก่อนจริง แต่ข่าวก็ยังค้างอีก คราวนี้ต้นเหตุคนละแบบ
โค้ดขอมาแบรนด์ละ 4 ข่าว แล้วเอามาผ่าน ด่านกรองความเกี่ยวข้อง ที่บังคับว่าพาดหัวหรือชื่อสำนักข่าวต้องมีชื่อแบรนด์อยู่ ปรากฏว่าสี่อันแรกของแต่ละแบรนด์โดนด่านตีตกเป็นประจำ ของที่ผ่านด่านได้จริงไปกองอยู่ลำดับ 5 ถึง 10 ซึ่งถูกตัดทิ้งตั้งแต่ยังไม่ได้ดู
ผมวัดจริงในวันเดียวกัน ยิงเท่ากันทั้งสองรอบ
ผ่านด่าน 2 ข่าว · ใหม่สุดคือ 4 ก.ย.
- ยิง API 21 ครั้ง
- สี่อันแรกถูกตีตกเกือบทุกแบรนด์
- หน้าเว็บนิ่งสนิท
ผ่านด่าน 13 ข่าว · ใหม่สุดคือ 6 ก.ย.
- ยิง API 21 ครั้งเท่าเดิม
- ของที่ผ่านด่านอยู่ลำดับ 5-10 ได้เข้ามา
- ต้นทุนต่อวันเท่าเดิมทุกประการ
จุดที่ผมอยากให้เห็นคือ โควตาของบริการพวกนี้คิดเป็นจำนวนครั้งที่ยิง ไม่ใช่จำนวนรายการที่ได้กลับมา เพราะฉะนั้นการขอมาน้อยกว่าเพดานที่เขาให้ ไม่ได้ประหยัดอะไรเลยสักบาท แต่ทำให้ของที่ผ่านด่านหายไปเฉยๆ ผมเลยตั้งค่าปริยายเป็นเพดานที่ผู้ให้บริการยอมให้ แล้วเขียนคอมเมนต์กำกับไว้เลยว่าห้ามลดกลับ
# ขอมาให้เต็มเพดานที่ผู้ให้บริการยอมให้ต่อหนึ่งคำค้น
# ห้ามลดค่านี้ลง: โควตาคิดเป็น "จำนวนครั้งที่ยิง" ไม่ใช่ "จำนวนข่าวที่ได้"
# ลดลงเมื่อไรของที่ผ่านด่านกรอง (ซึ่งมักอยู่ลำดับ 5-10) จะถูกตัดทิ้งตั้งแต่ยังไม่ได้ดู
PER = int(sys.argv[sys.argv.index("--per") + 1]) if "--per" in sys.argv else 10
for key, q, must in BRANDS:
url = ("https://api.example.com/v4/search?q=%s&lang=en&max=%d&sortby=publishedAt&apikey=%s"
% (urllib.parse.quote(q), PER, KEY))
d, err = call(url)
used += 1
if err:
print(" %-20s ERR %s" % (key, err))
if "429" in err or "403" in err:
quota_hit = True; break # ชนโควตาแล้ว หยุดเลย อย่ายิงต่อให้โดนแบน
time.sleep(1.1); continue
...
time.sleep(1.1) # เพดาน 1 ครั้งต่อวินาที เว้นจังหวะเอง
ด่านกรอง: จำเป็น แต่ต้องเลือกคำให้เป็น
ตอนผมขยายคำค้นให้กว้างขึ้นเพื่อหาข่าวเพิ่ม สิ่งที่ตามมาทันทีในวันเดียวกันคือ ข่าวรีวิวรถยนต์ ข่าวเกษตรจังหวัด และข่าวประชาสัมพันธ์ของบริษัทที่ไม่เกี่ยวอะไรเลย ขึ้นไปนอนอยู่บนเว็บข่าวเฉพาะทาง เพราะเครื่องมือค้นภาษาไทยมันจับคู่หลวมมาก คำค้นที่เอาชื่อแบรนด์มาต่อกับคำสามัญประจำอุตสาหกรรมก็แมตช์ได้เกือบทุกอย่าง
ด่านกรองของผมเลยบังคับว่า พาดหัวหรือชื่อสำนักข่าวต้องมีชื่อแบรนด์อยู่จริง และมีกับดักซ้อนอยู่ในด่านนี้อีกสองข้อ
def norm(s):
# พาดหัวไทยเว้นวรรคชื่อแบรนด์ไม่เหมือนกัน ("สตาร์ไลน์" กับ "สตาร์ ไลน์")
# ถ้าไม่ตัดช่องว่างก่อนเทียบ ข่าวจริงของแบรนด์จะโดนตีตกทิ้งว่าไม่เกี่ยว
return "".join((s or "").lower().split())
def relevant(it, must):
if not must:
return True # ไม่ได้ตั้งคำไว้ -> เก็บ อย่าเงียบๆ ทิ้งประวัติ
hay = norm((it.get("title") or "") + " " + (it.get("source") or ""))
return any(norm(t) in hay for t in must)
ข้อแรกคือเรื่องช่องว่าง ตอนผมยังเทียบแบบไม่ตัดช่องว่าง ข่าวจริงของแบรนด์หนึ่งโดนตีตกทิ้งเป็นประจำเพราะพาดหัวเว้นวรรคกลางชื่อ พอเปลี่ยนมาตัดช่องว่างก่อนเทียบ จำนวนที่เก็บได้ขยับจาก 30 เป็น 35 ในรอบเดียว
ข้อสองคือเรื่องการเลือกคำ ห้ามใช้ชื่อประเทศ ชื่อเมือง หรือคำสามัญเป็นคำด่านเด็ดขาด ผมเคยใช้ชื่อประเทศตัวหนึ่ง ผลคือได้ข่าวไว้อาลัยเชื้อพระวงศ์ของประเทศนั้นกับข่าวราคาน้ำมันของอีกประเทศเข้ามาเต็มไปหมด อีกแบรนด์หนึ่งชื่อไปพ้องกับชื่อผ้าชนิดหนึ่ง และตัวย่อสามตัวอักษรนี่แมตช์ได้กับทุกอย่างบนโลก ต้องใช้ชื่อแบรนด์เต็ม ไม่ใช่คำที่อยู่ในชื่อแบรนด์
มีอยู่สี่แบรนด์ที่ผ่านด่านได้ศูนย์ข่าวติดกันหลายวัน ผมไปนั่งไล่ดูของที่ถูกตีตกทีละชิ้น ปรากฏว่าด่านทำถูกแล้ว ข่าวที่ค้นเจอเป็นข่าวรวมกลุ่มอุตสาหกรรมที่ไม่ได้พูดถึงแบรนด์นั้นจริง ถ้าผ่อนด่านลงเพื่อให้ตัวเลขสวย ผลที่ได้คือเอาข่าวภัยธรรมชาติไปแปะชื่อแบรนด์ ซึ่งแย่กว่าการไม่มีข่าวเยอะ
ไฟล์สะสมไปเรื่อยๆ เลยต้องมีตัวไล่ล้างย้อนหลัง
จุดที่คนมักลืมคือ ไฟล์ผลลัพธ์ของผม สะสมไปเรื่อยๆ ไม่เคยลดลง โค้ดมันเขียนไว้ว่า items = list(prev) แล้วเติมของใหม่ต่อท้าย และตัวเผยแพร่ยิงทั้งลิสต์ขึ้นไปแบบแทนที่ทั้งชุด แปลว่าอะไรก็ตามที่ด่านเคยปล่อยผ่านตอนที่ยังไม่มีด่าน มันจะอยู่บนเว็บตลอดกาล เพราะสตรีมข่าวสายนี้ไม่มีขั้นตอนใช้วิจารณญาณคั่นเลยสักขั้น
ผมเลยเขียนตัวไล่ล้างแยกอีกตัว ใช้ตารางคำด่านชุดเดียวกันไปกวาดของที่เก็บไว้แล้ว โดยให้เป็นโหมดดูเฉยๆ เป็นค่าปริยาย ต้องสั่ง --apply เท่านั้นถึงจะเขียนทับ
def main():
j = json.load(io.open(ENP, encoding="utf-8"))
items = j.get("items", [])
keep = [i for i in items if relevant(i, MUST.get(i.get("key", "")))]
drop = [i for i in items if i not in keep]
print("ไฟล์สะสม: %d รายการ | เก็บ %d | ทิ้ง %d" % (len(items), len(keep), len(drop)))
for d in drop[:20]:
print(" DROP [%s] %s | %s" % (d.get("key"), d.get("date"), (d.get("title") or "")[:64]))
if "--apply" not in sys.argv:
print("\n(โหมดดูเฉยๆ — ใส่ --apply ถึงจะเขียน แล้วค่อยสั่งเผยแพร่ซ้ำ)")
return
j["items"] = keep
json.dump(j, io.open(ENP, "w", encoding="utf-8"), ensure_ascii=False, indent=1)
print("\nเขียนแล้ว %d รายการ ต่อไปสั่งเผยแพร่เฉพาะส่วนข่าวเพื่อ sync ของจริง" % len(keep))
รอบนั้นผมใช้มันไล่เก็บของที่หลุดเข้ามาตอนยังไม่มีด่าน ได้ข่าวนอกเรื่อง 11 ชิ้น กับข่าวที่แมตช์ผิดจากคำด่านที่เป็นชื่อประเทศอีก 3 ชิ้น
ด่านตรวจความสด: ทำให้งานล้มดังๆ แทนที่จะเงียบ
สามข้อข้างบนคือการซ่อมเหตุ แต่ของที่สำคัญกว่าสำหรับผมคือข้อนี้ เพราะอาการ "ค้างแบบเงียบ" เกิดกับผมซ้ำหลายรอบและทุกรอบต้องรอให้มีคนมาทัก ผมเลยเติมด่านสุดท้ายเข้าไปในตัวเผยแพร่ ให้มันดูวันที่ของข่าวใหม่สุดหลังทำงานเสร็จ ถ้าเก่าเกินเส้นที่ตั้งไว้ ให้พิมพ์เหตุผลแล้วคืนค่าไม่เป็นศูนย์
# เกินกี่วันถือว่าฟีดค้าง — ปรับผ่านตัวแปรสภาพแวดล้อมได้โดยไม่ต้องแก้โค้ด
STALE_DAYS = int(os.environ.get("FEED_STALE_DAYS", "2"))
def freshness_gate(items):
"""ตรวจ 'ผลลัพธ์' ไม่ใช่ 'ว่ารันจบ' — คืนค่าที่ไม่ใช่ศูนย์เพื่อให้ตัวตั้งเวลาขึ้นแดง"""
if not items:
print("[gate] ไม่มีรายการที่เผยแพร่ได้เลยในหน้าต่างเวลา -> ถือว่าล้ม")
return 1
newest = max((i.get("date") or "") for i in items)
cut = (datetime.date.today() - datetime.timedelta(days=STALE_DAYS)).isoformat()
if newest < cut:
print("[gate] ข่าวใหม่สุดคือ %s เก่ากว่าเส้น %s (FEED_STALE_DAYS=%d)"
% (newest, cut, STALE_DAYS))
print("[gate] แปลว่าต้นทางหยุดส่งของใหม่ หรือด่านกรองตีตกหมด -> ไปไล่ที่ต้นทาง")
return 1
print("[gate] ข่าวใหม่สุด %s ผ่าน" % newest)
return 0
sys.exit(freshness_gate(out) or report("feed"))
ค่าปริยาย 2 วันคือตัวเลขที่ผมเลือกจากจังหวะของงานจริง งานรันทุกวัน ถ้าสองวันแล้วยังไม่มีของใหม่เข้ามาเลย แปลว่าต้องมีคนไปดูแล้ว ใครที่ต้นทางออกข่าวถี่กว่านี้ก็ลดลงได้ตามใจ แต่อย่าไปตั้งไว้หลวมจนกลายเป็นด่านที่ไม่เคยทำงาน
เติมแหล่งที่สอง แล้วปัญหาเดิมกลับมาทันที
พอทำทั้งหมดข้างบนเสร็จ ยังมีอีกหกแบรนด์ที่หาข่าวภาษาอังกฤษไม่เจอเลย ผมเลยเติมแหล่งที่สองเป็น RSS ภาษาไทย ซึ่งฟรี ไม่ใช้คีย์ ไม่มีโควตา และคืนได้ถึงร้อยรายการต่อคำค้น เอามาคั่นระหว่างตัวรวมข่าวกับตัวเผยแพร่ เติมรายการลงไฟล์เดียวกัน รูปแบบเดียวกัน ขั้นถัดไปไม่ต้องแก้อะไรเลย
# ต่อเข้าลำดับงานประจำวัน คั่นระหว่างตัวรวมข่าวกับตัวเผยแพร่
python feed_api.py --per 10
python feed_rss.py --all --days 10 --per 6
python feed_publish.py --days 21 --max 24
แต่ที่ต้องย้ำคือ แหล่งที่สองนี้คือแหล่งเดียวกับที่มีกับดักข้อแรก คือเรียงตามความเกี่ยวข้อง ผมยืนยันซ้ำด้วยของจริงอีกรอบว่าลำดับที่ได้คือ 2 ก.ย. แล้ว 6 ก.ย. แล้ว 3 ก.ย. เพราะฉะนั้นตัวใหม่นี้ต้องแปลง pubDate เป็นวันเวลาจริงแล้วเรียงเองก่อนตัดเหมือนกัน ไม่งั้นได้ข่าวเก่าชุดเดิมทุกวัน
ผลวันแรกของแหล่งที่สอง เติมเข้ามา 19 ข่าว รวมกับของเดิมอีก 5 เป็นฟีด 24 ข่าว หน้าเว็บได้ข่าวของวันนี้กับเมื่อวานขึ้นชัดเจน ข้อเสียคือ RSS ไม่มีรูปประจำข่าว ตัวเผยแพร่เลยต้องถอยไปใช้รูปสำรองประจำแบรนด์ รอบแรกได้รูปจริง 26 จาก 40 ที่เหลืออีก 14 ใช้รูปสำรอง ซึ่งผมรับได้
ลำดับที่ผมใช้ไล่เวลาเจออาการแบบนี้
- เทียบผลลัพธ์กับเมื่อวานก่อน ไม่ใช่ดู log ก่อน ถ้าจำนวนรายการเท่าเดิมเป๊ะ แปลว่าไม่มีของใหม่เข้าระบบ ไม่ใช่ระบบพัง
- ไล่ย้อนจากปลายขึ้นต้นทาง ถามทีละชั้นว่า "ชั้นนี้ได้ของใหม่เข้ามากี่ชิ้น" ไม่ใช่ "ชั้นนี้รันสำเร็จไหม"
- พอเจอชั้นที่ได้ศูนย์ ให้พิมพ์ของดิบที่ชั้นนั้นรับเข้ามาทั้งหมดออกมาดูด้วยตา โดยเฉพาะลำดับและวันที่
- แยกให้ออกว่า "ต้นทางไม่มีของ" กับ "ด่านกรองตีตก" กับ "ตัดทิ้งก่อนถึงด่าน" เป็นคนละอาการ วิธีแก้คนละทาง
- ซ่อมเสร็จแล้วเติมด่านตรวจผลลัพธ์ไว้ท้ายสุดทุกครั้ง ให้รอบหน้ามันขึ้นแดงเอง ไม่ต้องรอคนมาทัก
สรุปสิ่งที่เปลี่ยน
เรื่องนี้ไม่มีบั๊กที่หน้าตาเหมือนบั๊กเลยสักตัว ทุกอันคือโค้ดที่ทำงานถูกตามที่เขียน แต่สมมติฐานที่อยู่ข้างใต้มันผิด ทั้ง "ฟีดเรียงตามวันที่ให้แล้ว" ทั้ง "สตริงวันที่เรียงได้" ทั้ง "ขอมาน้อยลงคือประหยัด" สามข้อนี้ฟังดูสมเหตุสมผลทั้งหมดตอนเขียน และไม่มีข้อไหนที่จะส่งเสียงตอนมันผิด
ส่วนตัวผมถ้าให้เลือกทำได้แค่อย่างเดียวจากทั้งหมดนี้ ผมเลือกด่านตรวจความสดในหัวข้อที่แล้ว เพราะอีกสามข้อคือการแก้ปัญหาที่เจอแล้ว แต่ข้อนั้นคือสิ่งที่จะบอกผมเองว่าเจอปัญหาใหม่ที่ยังไม่รู้จัก ที่เหลือใครจะจัดลำดับยังไงก็ตามสะดวกครับ
ปล. ถ้าต้นทางของใครออกของไม่สม่ำเสมอจริงๆ เช่นบางสัปดาห์เงียบไปทั้งอาทิตย์ อย่าเพิ่งตั้งด่านความสดให้ล้ม ให้เริ่มจากส่งเตือนอย่างเดียวก่อนสักสองสามสัปดาห์ จับจังหวะจริงของต้นทางให้ได้ก่อน แล้วค่อยตั้งเส้น ไม่งั้นจะได้แจ้งเตือนลวงจนคนเลิกอ่าน เดี๋ยวกลับมาแก้เพิ่มให้ภายหลังครับ
เคยเจองานแบบนี้ไหม? ติดตรงไหน?
มาแลกวิธีกันต่อในบอร์ด LinuxThai



ความคิดเห็น 0
ยังไม่มีความคิดเห็น — เป็นคนแรกเลย