บทความนี้ได้แรงบันดาลใจจากเพื่อน ThoughtWorks ที่เคยเป็น partner กับบริษัทผม โดยเค้าเสนอให้ลองใช้ high-order function ในการเขียน Scala ซึ่งเป็น functional programming language อยู่ละ

ตัวอย่างโค้ด

เป็นตัวอย่างโค้ดของ Spark streaming application มาในรูปแบบ Input Stream => Streaming Computation => Output Sink
คำถามตอนนั้นคือ เราจะปรับปรุง code นี้ให้ดีขึ้นไปอีกยังไง

Spark https://databricks.com/blog/2016/07/28/continuous-applications-evolving-streaming-in-apache-spark-2-0.html

ว่าด้วยเรื่องของ Functional programming

รูปแบบ code ลักษณะนี้ที่เจอคือการเขียนแบบ Imperative style ซึ่งจะเน้นเป็นการอธิบายขั้นตอนการทำงานไปเรื่อยๆ แต่ปัญหาที่เกิดคือ ถ้าในอนาคตมันมี computation มากขึ้นไปเรื่อยๆ แปลว่าขั้นตอนมีมากขึ้น การจัดการ ดูแลรักษาเริ่มยากขึ้น เลยนำ Object-Oriented Programming (OOP) มาใช้ (Scala ก็เขียน OOP ได้นะครับ) ซึ่งก็ช่วยจัดกลุ่ม behavior ที่เกี่ยวข้องกันได้อยู่ แต่การเขียนใน Streaming app ก็เป็นแบบเดิมอยู่ดี

ถ้าเราเปลี่ยนจากการเขียนแบบนี้

val input = fromInputStream
val df1 = compute
val df2 = computeMore
val output = toOutputSink

เป็นแบบนี้หละ

fromInputStream andThen
    compute andThen
        computeMore andThen
            toOutputSink

เริ่มใช้ High-order function ใน Scala

อธิบายง่ายๆ คือ function ที่ return function อีกที เช่น function map ใน salaries.map(x => x * 2) หมายความว่ามัน return function ซึ่งนำ x ไปคูณ 2 อีกที

ส่วนการสร้าง SparkSession

เป็นส่วนแรก return function ที่ไม่รับอะไรเลย (Void) ที่ return SparkSession อีกที

ส่วนการทำ Input-Output

ฝั่ง Input รับต่อมาจากการสร้าง SparkSession ซึ่ง return DataFrame อีกที
ฝั่ง Output รับ DataFrame มาจากการทำ computation เสร็จ แล้วก็ return StreamingQuery อีกที

ส่วนการทำ computation

ตรงนี้ก็ return function ที่รับ DataFrame มาจาก Input stream ที่ return DataFrame อีกที

เอามารวมกันจะได้หน้าตาประมาณนี้

ทำการร้อย function เข้าด้วยกัน (compose) ผ่าน andThen โดย function ถือ reference ของอีก function นึงไปเรื่อยๆ จนกว่าจะจบ flow

จริงๆ มันก็เหมือนกับการเขียนแบบนี้ แต่อ่านง่ายกว่าเยอะ ฮ่าๆๆ

การแก้ชุดการทดสอบก็ไม่ใช่เรื่องใหญ่อะไร

เป็นอีกแนวทางนึงในการอธิบาย code ของเราว่าทำอะไร (what) มากกว่าทำยังไง (how) ครับ
ตัวอย่างโค้ด https://github.com/raksit31667/example-spark-gradle