แชร์ประสบการณ์ Config ตัว Amazon ElastiCache ให้ใช้งานกับ Spring Boot

Story 2 - 3 วันที่ผ่านมาพยายามต่อ Redis บน ElastiCache แล้ว Error ตลอดเวลาเรียกใช้ จะมี Log ขึ้นประมาณข้างล่างนี้ แล้วแก้จนมันใช้ได้แล้วเอาขึ้น Server ไปละ นี่คือเรื่องของมัน org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to ███████-cache.███████.com:6379 Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to ███████-cache.███████.com:6379 e Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching ███████-cache.███████.com found. สันนิษฐานแรกคือน่าจะเกี่ยวกับ In-Transit Encryption feature ของ ElastiCache’s Redis ซึ่งถูกเลือกไว้แล้ว แล้วหลังจาก Research ไปซักระยะเลยเจอว่า ElastiCache’s Redis allow ให้ Connect ผ่าน VPC เท่านั้น ...

December 24, 2020 · 3 min

รีวิวคอร์ส Mathematics for Working Programmers

อยากจะพูดถึงคอร์ส Mathematics for Working Programmers ของอาจารย์เดฟ Dave Rawitat Pulam ที่เพิ่งรอดกลับมาหลังจาก 2 วันที่หนักหน่วงหน่อยครับ “ทำไมต้อง Refactor ถ้าเรา Prefactoring ได้ตั้งแต่แรก” นั่นคือประโยคที่ผมชอบที่สุดตลอดสองวันที่ผ่านมา ต้องบอกว่าก่อนไปเรียนคือ ผมไม่รู้เลยว่าจะไปเจอกับอะไรบ้าง แต่ก็มั่นใจระดับนึงว่าประสบการณ์เขียนโปรแกรมที่มีมันน่าจะพาเราเอาตัวรอดไปได้ระดับนึงละ พอผ่านไปไม่กี่สไลด์เท่านั้นแหละผมคิดผิด และผมเลยเพิ่งรู้ตัวเลยว่าผมมองโลกผ่านรูกุญแจมาตลอด อารมณ์เหมือน Dr.Strange เจอ Ancient One ครั้งแรกเลย เบิกเนตรแรกเลยคือ ผมไม่เคยรู้จัก State machine, Turing Machine ฯลฯ อะไรเลย แต่มารู้ในคอร์สนี้แหละว่าสิ่งนี้มันกำหนดวิธีมองโลก (ผ่านรูกุญแจ) ของผมมาตลอดหลายๆ ปีเลย ได้รู้จักคณิตศาสตร์ในมุมที่มันสวยงาม ไม่ใช่แรงงาน เหมือนกลับไปอ่านเรื่องราวของพอล แอร์ดิชกับรามานุจัน อีกครั้ง แต่ในขณะที่ตื่นตากับการเบิกเนตรครั้งที่หนึ่งและรู้สึกว่าการรู้สิ่งนี้จะทำให้เราเข้าใจโลกมากขึ้น อาจารย์เดฟก็เขย่าโลกครั้งที่สองครับด้วย lambda calculus เบิกเนตรครั้งที่สองพาผมย้อนกลับไปรู้จักกับความเรียบง่ายของ Function อีกครั้งที่เคยเรียนเมื่อเกิน 10 ปีที่แล้ววิธีคิด และค่อยๆ ไต่ระดับไปจนถึงจุดที่มัน “Equivalent” กันซึ่งคลาสนี้มันจะมีหลายจุดมากๆ ที่ระหว่างเรียนเราต้องสู้กับจิตใจตัวเองในการ unlearn ความเข้าใจที่เราเข้าใจมาตลอดหลายๆ ปี ซึ่งบางจุดก็ง่าย แต่บางจุดนั้นมันก็ยากจริงๆ ครับแต่ eventually เราจะเข้าใจมันเอง จุดที่ผมประทับใจมากอีกจุดนึงคือเรื่อง Type ครับ ตลอดชีวิตการเขียนโปรแกรมมาหลายปี หนังสือไม่รู้กี่เล่ม Talk ไม่รู้กี่ตัว ไม่เคยมีใครเล่าเรื่อง Type ได้เห็นภาพขนาดนี้และผมจะรู้สึกผิดมากถ้าผมมาเล่าสปอยไว้ตรงนี้ เพราะอยากให้คนอื่นได้ฟังจากในคอร์สนี้เองจริงๆ ...

December 7, 2020 · 1 min

อย่าเผลอรัก Design ตัวเอง มาทำความรู้จักกับ Second-System effect กัน

เคยมั้ยครับ เวลาเรา Discussion ในทีมเกี่ยวกับวิธี Implementation ของฟีเจอร์หนึ่งๆ แล้วเราหรือแม้แต่คนอื่นในทีมจะมีโมเม้นต์ประมาณว่า “กับฟีเจอร์นี้นะ เราเคยทำแบบนี้ A B C D นะ ต้องทำอย่างนี้สิ เราเคยทำมาแล้วมันเวิร์ค” แล้วหลังจากนั้นทีมก็ตกลงทำฟีเจอร์ด้วยวิธีนี้แล้วผ่านไปก็ค้นพบว่า ทำไมพอจะทำอะไรๆ ต่อมันยากไปหมดนะ รู้จักกับ Second-System Effect สถานการณ์แบบที่กล่าวมาข้างต้นนั้น ไม่ใช่เรื่องใหม่ครับและ ไม่ใช่เรื่องใหม่ในวงการ Software ด้วย ย้อนไปในปี 1975 Fred Brooks ได้พูดถึง Second-System Effect ไว้ในหนังสือ The Mythical Man-Month ว่า งานแรกของ Architect มักจะค่อนข้างกั๊ก เค้าจะรู้ตัวว่าเค้าไม่รู้อะไรบ้างในงานที่เค้าทำ เลยทำให้เค้ามีความระวังค่อนข้างมากเป็นพิเศษ ระหว่างที่เค้า Design งานตัวเองไป เค้าจะค้นพบท่าใหม่ๆ ทีละเล็ก ทีละน้อยแต่ก็จะยังไม่เอามาใช้เต็มที่และเก็บเอาไว้ใช้ “คราวหน้า” ผ่านไปไม่นาน ระบบแรกก็จะเสร็จและ Architect ที่เต็มไปด้วยความภูมิใจและมั่นใจในการสร้างระบบก็พร้อมที่จะสร้างระบบที่สองละ ระบบที่สองที่ Architect ออกแบบจะเป็นระบบที่อันตรายที่สุดที่เค้าเคยออกแบบ เมื่อเค้าออกแบบระบบที่ 3 และต่อๆ ไป ประสบการณ์ก่อนหน้านั้นจะช่วยยืนยันตัวเองว่า ระบบหนึ่งๆ นั้นมีความแตกต่างกันในแต่ละส่วนและไม่สามารถที่จะทำให้เหมือนกันได้ ซึ่งหลายๆ ครั้งพอเป็นระบบแนวๆ ที่เราเคยทำมาแล้ว เราก็มักจะเลือกวิธีที่เราเคยทำใช่มั้ยครับ เพราะเรารู้รายละเอียดที่สุด แต่ต้องระวังว่า ในความเหมือนนั้น มันก็จะมีความแตกต่างอยู่ และหลายๆ ครั้งเรามักจะ Over Design เกินกว่าความเป็นจริงไปโดยไม่รู้ตัว ...

November 9, 2020 · 2 min

เรากลับมาทำ BuJo ได้หนึ่งเดือนแล้ว

ในโลกที่วุ่นวาย และงานที่ถาโถม ทำให้ตลอดชีวิตที่ผ่านมา ไม่ทางใดก็ทางหนึ่ง ผมมักจะหาทางจัดการตัวเองผ่านอะไรซักอย่าง ซึ่งอาจจะเป็นได้ทั้ง Planner, Todo list, Trello Board, Post it ฯลฯ ซึ่งผมก็น่าจะเรียกว่าลองมาเยอะพอสมควร จนผมมาเจอ Bujo หรือ Bullet Journaling เมื่อ 2 ปีที่แล้วครับ ความเดิมตอนที่แล้ว แนะนำ BuJo เมื่อชีวิตอยากติด Analog บล็อกเต็มๆ ที่ผมเขียนเมื่อสองปีที่แล้วที่คนเข้ามาอ่านตอนนี้เกิน 40k คลิกไปแล้ว โพสนี้จะเรียกได้ว่าเป็นภาคต่อของบทความนั้นก็ได้ เรื่องราวหลังจากผมใช้ Bujo ได้ไม่กี่เดือนตอนนั้นคือ ผมถอย iPad ครับ และนั่นน่าจะเป็นจุดเริ่มต้นที่ผมกลับมาหาโลก Digital อีกรอบนึง ถึงแม้ว่าจะพยายามทำ Bujo บน GoodNotes เท่าไร แต่ก็ยอมรับว่าสัมผัสการเขียนใน iPad ยังไงมันก็ยังสู้กระดาษและปากกาไม่ได้ แต่ผมว่าเหตุผลที่สำคัญที่สุดที่ทำให้ผมหยุดทำ Bujo ไปในรอบนั้นคือความ Digital Native ของมันครับ นิยาม Digital native ของผมคือการพิมพ์ การถ่ายรูป Capture screenshot ฯลฯ ซึ่งนั่นทำให้เราขาดคีย์สำคัญของ Bujo ไปข้อนึงซึ่งผมไม่ได้คิดถึงตอนนั้น คือความสามารถในการประมวลผลข้อความแล้วสรุปครับ หรือทาง Bujo น่าจะเรียกว่า Rapid logging ทำให้ตอนนั้นวิธีการจดของผมเปลี่ยนไปมากคือ ด้วยความที่เป็นคนพิมพ์สัมผัสได้อยู่แล้ว เลยจดมันทุกอย่าง แล้วหลายๆ อย่างจนไม่ได้เอากลับมาคิดว่าจดไปทำไมนะ ซึ่งสุดท้ายผมก็เลิกทำ Bujo ไปแล้วแทนที่ด้วยอะไรก็ไม่รู้ ไม่มีชื่อเรียก แล้วแต่ tools จะพาไป ...

November 2, 2020 · 2 min

บันทึกวิธีใช้ liquibase ทำ database migration ให้ Spring boot

Installation ลง Liquibase ใน pom.xml <dependencies> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>3.6.2</version> </dependency> </dependencies> เพิ่ม configuration ให้ liquibase ใน application.properties ## Liquibase spring.liquibase.enabled=true spring.liquibase.parameters.EnumDataType=ENUM('VALUE1', 'VALUE2', 'VALUE3') spring.liquibase.contexts=local ตัวสำคัญคือ spring.liquibase.contexts ตัวนี้เหมือนคอยบอกว่าเรารัน Spring โหมดอะไรอยู่ แล้วทำให้เราใช้ connection database ที่เราเซตไว้ใน spring ได้ด้วย อีกจุดนึงคือ spring.liquibase.parameters อันนี้เป็น custom parameter ที่เราเอาไว้ใช้ใน Changeset ซึ่งบางครั้งของ database คนละแบบจะต่างกันอย่างเช่น type ENUM ของ H2 เก็บเป็น enum ได้เลย แต่ PostgreSQL ตัว spring จะแปลงเป็น INT เลยต้องมาประกาศไว้ด้วย Usage เพิ่มไฟล์ ChangeLog master ไฟล์นี้เป็นเหมือนไฟล์หลักไว้บอกว่ามี migration step อะไรบ้างผ่าน property ชื่อ include.file ไฟล์กับชื่อจะอยู่ที่ /resources/db/changelog/db.changelog-master.yaml ตัวนี้สามารถตั้งค่าให้ไปอยู่ที่อื่น ชื่ออื่นได้ แต่อันนี้คือชื่อ default หน้าตาของไฟล์จะประมาณ databaseChangeLog: - include: file: db/changelog/001-add-user-table.yaml สร้าง ChangeSet ตัวนี้ไว้บอกว่าใน migration นี้มี change อะไรเกี่ยวกับ database บ้าง ตัวอย่างเช่นของ user databaseChangeLog: - changeSet: id: 001-add-user-table author: man changes: - createTable: columns: - column: constraints: nullable: false primaryKey: true primaryKeyName: user_pkey name: id type: UUID - column: constraints: nullable: false name: name type: VARCHAR(250) - column: constraints: nullable: false name: type type: ${EnumDataType} - column: name: is_admin type: BOOLEAN - column: name: created_at type: TIMESTAMP tableName: user ใน changeSet ต้องบอกว่ามันเป็น changeSet ซึ่งมี property หลักๆ ที่ใช้คือ ...

October 27, 2020 · 3 min

Backup Django ง่ายกว่านี้ไม่มีอีกแล้วด้วย django-dbbackup

ช่วงนี้ผมต้องมาขึ้น Django project ใหม่กับทีมครับ ซึ่งพอขึ้น Project ใหม่ หนึ่งใน Development workflow ที่มาคู่กันคือ การต้องเอา Database จาก Production กลับมาใช้ที่ Local development ให้ได้ เพื่อที่จะ debug ปัญหาหลายๆ อย่างได้กับ Data บน Production หรือ เพื่อความสะดวกสบายในการ Development ครับ ทีนี้ที่ผ่านมามันไม่ค่อยมีปัญหาเพราะ Database ผมมักจะใช้ PostgreSQL ซึ่งอาจจะอยู่ใน database Instance ของตัวเอง อยู่บน Container ของตัวเอง ฯลฯ ซึ่งก็ใช้ pg_dump กับ pg_restore คู่กันง่ายๆ มาตลอด ไม่มีปัญหายเว้นอัพเกรด PostgreSQL major version ที่ไฟล์ format เปลี่ยนนิดหน่อยก็ตามอัพเกรด client กัน ปัญหามันอยู่ที่ Media files ครับ ซึ่งถ้าเลือกได้ ผมจะเลือกใช้ django-storages เพื่อที่จะ offload ตัว media file ไปเก็บไว้ใน object storage เช่น Amazon s3 หรือ Google Cloud Storage ครับ แต่ใน use case ที่เราเลือกไม่ได้ต้องเก็บไฟล์ลง server เท่านั้น เราจะทำยังไงหละ ...

May 17, 2020 · 3 min

ใครว่า E2E เทสรันช้า เทคนิคง่ายๆ ที่จะทำให้ Cypress รันเร็วติดจรวด

เกริ่นก่อนว่าที่ Pronto Tools เราเปลี่ยนมาใช้ Cypress มาได้ซักพักแล้วครับแล้วเราชอบมันมาก เราเลยไม่ลังเลเลยที่จะย้ายและเพิ่ม E2E เทสมาอยู่บน Cypress ซึ่งพอเทสมันเพิ่มขึ้นอย่างรวดเร็ว เวลาที่ใช้รันมันก็เพิ่มขึ้นอย่างมีนัยยะสำคัญ ทำไม E2E เทสถึงรันช้า 🐢 ปัญหาหลักเลยคือ E2E เทสจะค่อนข้างมี Step ที่ทำงานซ้ำๆ เกิดขึ้นบ่อยๆ เพื่อ Setup ข้อมูลให้พร้อมที่จะเทสใน TestCase หลัก ปัญหาหลักๆ ก็คืองานซ้ำๆ นั้นถ้ามันใช้เวลารันนาน ถ้ามันยิ่งมีจำนวนมากขึ้นก็จะยิ่งทำให้ชุดทดสอบเราทำงานช้าขึ้นเรื่อยๆ ลองมาดูตัวอย่างของเทสกันครับ describe('Pricing plan page', () => { context('Product Plan Section', () => { it('Should see Product title', () => { cy.signUp() cy.visit('/plan') cy.get('.plan-title').should('contain', 'Basic Plan') }) it('Should see price', () => { cy.signUp() cy.visit('/plan') cy.get('.plan-price').should('contain', '$599') }) }) }) จากโค้ดตัวอย่างข้างต้น จะเป็นการเทสว่าหน้า Pricing Plan เราเนี่ยมันมีชื่อ Plan กับราคาอยู่ ซึ่งจะเห็นว่าการจะทดสอบ TestCase นึงนี่ เราต้องเสียเวลาไปรัน command cy.signUp() ซึ่งเป็น command ที่เราสร้างให้เอาไว้สมัครสมาชิกเข้า service เรา ซึ่งเวลาสมัครใช้งานเนี่ย มันจะมีการทำงานหลายอย่างเกิดขึ้นไม่ว่าจะเป็น สร้าง subscription user, ส่งอีเมล์ยืนยันการสมัคร, ฯลฯ แต่ละอย่างนี่ใช้เวลาทั้งนั้นครับ ...

May 17, 2019 · 4 min

2018

ปีนี้โดยรวมเป็นปีที่ไม่ค่อยรู้สึกดีกับตัวเองเท่าไร และอยู่กับความรู้สึกแบบนั้นมาตลอดปี สิ่งสำคัญที่ได้เรียนรู้จากเรื่องราวทั้งหมดในปีที่ผ่านมาคือ ถ้าอยากทำอะไรแล้วทำไปเลย อย่ารอให้มันพร้อมแล้วค่อยทำ เพราะสิ่งที่รู้สึกไม่ค่อยดีทั้งหลายส่วนใหญ่ในปีนี้ก็เกิดจาก สุดท้ายมันจะไม่ได้ทำนี่แหละ Finance 💸 หลังจากปีที่แล้วทำการ Reset หนี้ทั้งหมดแล้วเริ่มต้นใหม่ สิ่งที่ได้เรียนรู้ปีนี้คือ ไม่มีหนี้อะดี แต่ไม่มีหนี้แล้วไม่มีตังค์อ่ะไม่ดี คือ ช่วงแรกๆ ยังติดใจความรู้สึกไม่มีหนี้อยู่ แต่พอเวลาผ่านไปเริ่มรู้สึกว่าทำไมเงินมันไม่ต่างจากเดิมเลย เป็นเพราะว่าถึงแม้จะเคลียร์หนี้หมด แต่การไม่ได้เก็บตังค์เพิ่มต่อ สุดท้ายมันก็เป็นการนับถอยหลังให้เงินหมดเหมือนเดิม ปีนี้เลยเปลี่ยน Strategy ใหม่ประมาณกลางๆ ปีคือ มีหนี้อะมีได้ แต่ต้องเป็นหนี้ที่ควบคุมและรับความเสี่ยงได้ พอคิดอย่างนี้ เลยทำให้ชีวิตมันปลดล็อก ได้อะไรหลายๆ อย่างที่อยากได้มาตลอดใน Worth mention เดียวก็เห็น นอกจากนี้แล้วปีนี้ได้เปิดเลนการลงทุนใหม่ด้วย หลังจากศึกษามานาน ปีนี้จัดกองทุนรวมไป 3 กอง ถึงแม้ตอนนี้ยอดไม่เยอะ แต่ถ้าเป็นไปตามแผน มันก็จะอยู่ไปด้วยยาวๆ อีกหลายปี Study 📚 ปีที่แล้วหัวข้อตรงนี้คือ Reading แต่ปีนี้อ่านหนังสือน้อยมาก อย่างมีนัยยะสำคัญ แต่สิ่งที่มากกว่าอ่านหนังสือคือ เรียนนี่แหละครับ และนี่คือคอร์สที่เรียนมาตลอดปีนี้ Node.js + GraphQL + Apollo workshop Apache Kafka Workshop Android A-Z Modern Agile Development Workshop Brush lettering Workshop ส่วนหนังสือปีนี้ซื้อหลายเล่มแต่ที่จำได้หลักๆ มี Principle, Sapiens และ It doesn’t have to be crazy at work ส่วนพวกลิ้ง Technical Blog ปีนี้จัดการได้ดีขึ้นโดยแทนที่จะดองไว้ใน bookmark ซักที่ก็พยายามจะอ่านทุกลิ้งให้มันจบซักวันภายในอาทิตย์นั้น แต่สิ่งที่ Improve ที่สุดคือติดนิสัย Zero Inbox และเลิกอ่านเมล Medium Daily Digest นี่แหละ ที่ทำให้จัดการ Knowledge พวกนี้ได้อยู่หมัด ...

January 1, 2019 · 4 min

10 Python libraries ที่เราชอบในปี 2018

เป็นธรรมเนียมที่พึ่งสร้างเป็นปีที่สองกันครับว่า เราจะมามองย้อนกลับไปในปี 2018 ที่กำลังจะผ่านพ้นไปว่า Python Libraries ตัวไหนที่เราชอบบ้าง ของปีที่แล้วเราคัดมา 10 Libraries ปีนี้เราก็จะคัดมาอีก 10 เหมือนกันครับ แต่ลำดับไม่มีผลอะไรนะครับ ไปดูกันเลย Source: https://github.com/ambv/black \1. Black — The uncompromising code formatter Source: https://github.com/ambv/black ในสมัยก่อนพอพูดถึง Formatter ของ Python เราจะนึกถึงแค่ yapf เป็นหลัก รองลงมาก็ autopep8 ซึ่งก็มีฐานผู้ใช้ระดับนึง ปีนี้เรามีเจ้าใหม่เข้ามาในตลาดครับ ซึ่งก็คือ Black นี่เอง จุดเด่นของ Black คือ just work ครับลงปั๊ปใช้ได้เลย หรือถ้าอยากจะ config ก็ได้นิดหน่อย อีกจุดเด่นที่ทุกคนที่ได้ลองใช้ Black พูดถึงและมีทั้งชอบและไม่ชอบคือใช้ double quotes (“) มากกว่า single quotes (‘) ครับ แต่หลายๆ คนพอใช้แล้วก็ยังพิมพ์ single quotes เหมือนเดิมรวมทั้งผมด้วย แล้วปล่อยให้ Black มันจัดการไปครับ นอกจากนั้นแล้วตัว Black ยัง Optimize ให้ใช้กับ syntax ใหม่ๆ ที่มีใน Python 3.6+ และ stub file สำหรับเขียน type signature ของ function ด้วยครับ ...

December 29, 2018 · 4 min

PEP 8016 and the future of Python govenance

อย่างที่ทุกคนรู้นะครับว่า Guido ได้ถอดตัวออกจากการเป็น BDFL Role ที่เป็นมาอย่างยาวนานในช่วงกลางปีที่ผ่านมา แล้วการออกนั้นถึงแม้จะไม่ได้ effect กับ user อย่างเราๆ ท่านๆ แต่มีผลมากกับ Core developer ที่คอยดูแล CPython กับ Python Interpreter อยู่ครับ ด้วยเหตุนี้เองประมาณเดือนสิงหาคมที่ผ่านมาทาง Core Dev หลายๆ คนจึงช่วยๆ กันร่างมาตรฐาน PEP 8001 — Python Governance Voting process ขึ้นมาเป็นอันดับแรกครับ ซึ่งจะพูดถึงวิธีการ vote มาตรฐาน Governance ก่อน โดยจะเปิดให้ Core dev 94 คนเป็นคน vote เพื่อเลือกมาตรฐาน Governance model สำหรับอนาคตต่อไป ในระหว่างนั้นก็ได้มี Core dev หลายๆ คนเสนอมาตรฐานหลายๆ มาตรฐานขึ้นมาหลายๆ ตัวครับ จนกระทั่งเดือนธันวาคมระหว่างวันที่ 1–16 จะเป็นช่วงเวลาที่คณะกรรมการการเลือกตั้งเปิดให้โหวตมาตรฐานแต่ละตัวที่มีคนเสนอมา จากที่ติดตามใน twitter นี่บอกได้เลยครับว่า หลายๆ Core dev รอกันจนวันสุดท้ายถึงตัดสินใจ และปิดโหวตในวันที่ 17 ที่ผ่านมานี่เองครับและมาตรฐานที่ได้รับเลือกคือ PEP8016 — The Steering Council Model ครับและเราจะไปดูรายละเอียดของมาตรฐานตัวนี้กันใน blog นี้ครับ ...

December 19, 2018 · 2 min