ทีมพัฒนาของ Digitalocean นั้นได้ออกมาเล่าถึงประสบการณ์การพัฒนาระบบงานด้วยภาษา Go
ซึ่งเป็นระบบงานภายในชื่อว่า Cthulhu
โดยเป็นระบบงานที่ใช้งาน version control แบบ Monorepo
นั่นคือ code ทุกสิ่งอย่างอยู่ใน repository เดียวกัน
แม้ว่าจะมีมากกว่า 1 project ก็รวมกันอยู่ในนี้

แน่นอนว่า ต้องเจอปัญหาต่าง ๆ มากมาย

ทั้งเรื่องของโครงสร้าง
ทั้งเรื่องการ scale
ทั้งเรื่องของการจัดการ dependency ต่าง ๆ
ทั้งเรื่องของเครื่องมือที่ใช้งาน
ทั้งเครื่องของเวลาในการ build ของ CI server
ทั้งเรื่อง code ownership

มาดูกันว่าทางทีม Digitalocean ทำอย่างไรบ้าง ?
น่าสนใจมาก ๆ

สถิติต่าง ๆ ของ repository

28,639 commits
824 branches
142 contributors
830,434 lines of DigitalOcean-authored Go code
2,136,373 lines of vendored Go code

โครงสร้างของ repository ของระบบเป็นดังรูป

คำอธิบาย

  • GOPATH คือ cthulhu/decode
  • do จะเป็น prefix ของ code ทุก ๆ อย่าง ซึ่งเป็น internal code ทั้งหมด
  • โดยที่ folder ใน do/ ก็จะแยกตามหน้าที่การทำงานไป
  • doge ย่อมาจาก DigitalOcean Go Environment เก็บ standard library ซึ่งใช้งานจากทุก ๆ service เช่น logging, metric และ RPC เป็นต้น
  • exp หรือ Experiment code เป็น code สำหรับการทดลองเรื่องต่าง ๆ
  • services แยกตาม service ของ DigitalOcean แต่ทำให้เกิดปัญหาว่าทีมไหนดูแล ดังนั้นจึงเปลี่ยนไปใช้ folder teams แทน
  • teams ทำการเก็บแต่ละงานแต่ละ service ของทีมไปเลย แต่ก็ยังมีปัญหาคือ แต่ละทีมไม่ sync กัน ทำให้โครงสร้างภายในแต่ละงานแตกต่างกัน
  • tools ทำการเก็บเครื่องมือต่าง ๆ ที่ใช้แบบเฉพาะงานไปเช่น CI/CD tool, static code analysis เป็นต้น
  • vendor สำหรับ 3-party library ที่ใช้ข้ามทีมหรือ service/project ซึ่งในโครงสร้างของ project แบบนี้ Go Vendor ไม่สนับสนุนนะ เพราะว่าทำได้เพียง vendor ที่ root project เท่านั้น แต่สิ่งที่ต้องการคือใน sub folder ดังนั้นจึงต้องทำเองใช้เอง
  • scripts เก็บ shell script ต่าง ๆ ที่ใช้งานใน CI/CD server หรือในกระบวนการ build เช่น compile, static analysis, testing และสร้าง binary สำหรับ deploy เป็นต้น

CI build tool

ข้อดีของ monorepo คือ code ทั้งหมดอยู่ที่เดียวกัน
ดังนั้นไม่ต้องกลัวเลยว่า code จะไม่ update
ไม่ต้องกลัวเลยว่า dependency จะไม่ update
แต่ผลที่ตามมาคือ เวลาในการ build มันสูงมาก ๆ

โดยในปี 2016 นั้นที่ DigitalOcean ใช้เวลาในการ build ถึง 20 นาที !!
ส่งผลให้การพัฒนาช้าเป็นอย่างมาก
ปัญหาจึงตามมาเพียบ ความเจ็บปวดเยอะสุด ๆ
ดังนั้นจึงทำการสร้างเครื่องมือมาใช้งานเองชื่อว่า gta (Go Test Auto)
ก่อนเริ่มการ build จะตรวจสอบ code ก่อนว่ามีการเปลี่ยนแปลงอะไร
กระทบส่วนไหนบ้าง
จากนั้นทำการ build และ test ในส่วนที่เกี่ยวข้องเท่านั้น
ซึ่งลดเวลาไปอย่างมาก
จาก 20 นาทีลงมาเหลือประมาณ 2-3 นาทีเท่านั้นเอง

Static Analysis Tool

ในทุก ๆ commit นั้นจะทำการตรวจสอบ code ก่อนเสมอ
ด้วย gofmt, go vet , go lint และอื่น ๆ อีกมากมาย
เพื่อทำให้มั่นใจในคุณภาพของ code
และในบางทีมก็มีเครื่องมือเฉพาะหรือสร้างขึ้นมาใช้เช่น staticcheck และ buildlint เป็นต้น
รวมทั้งยังใช้ godoc ในการสร้าง document ของทุก ๆ package ด้วยนะ

จากคำอธิบายที่ผ่านมาจะพบว่า

ปัญหาจะเปลี่ยนไปเรื่อย ๆ
ดังนั้นโครงสร้างและเครื่องมือต่าง ๆ ที่ใช้งานใน project ก็จะเปลี่ยนไปเรื่อย ๆ เช่นกัน
นั่นคือ
ความท้าทายที่ทีมต้องพบเจอและก้าวผ่านไปให้ได้
สิ่งที่ดีวันนี้อาจจะไม่ดีในวันหน้า
แต่ถ้าเวลานั้นมาถึงก็ต้องพร้อมที่จะรับมือด้วยเช่นกัน

ยกตัวอย่างเช่นการทดสอบของระบบ
ซึ่งเดี๋ยวทดสอบผ่านบ้างไม่ผ่านบ้าง
ยิ่งต้องทำงานร่วมกับระบบอื่น ๆ เช่น Database, Webservice เป็นต้น
ยิ่งก่อให้เกิดปัญหามากมาย
ซึ่งตรงนี้ทางทีมพัฒนาจะแก้ไขปัญหาต่าง ๆ ที่คิดว่าดี
และส่งผลให้การทดสอบมันเสถียรและน่าเชื่อถือเพิ่มขึ้น
แน่นอนว่า ความไว้เนื้อเชื่อใจต่อทีมนั้นสูงมาก
มันคือวัฒนาธรรมของทีมและองค์กรนั่นเอง

Reference Websites
https://blog.digitalocean.com/cthulhu-organizing-go-code-in-a-scalable-repo/
https://blog.gopheracademy.com/advent-2015/go-in-a-monorepo/
https://speakerdeck.com/farslan/go-at-digitalocean