Streaming Progress Update Menggunakan Go dan gRPC
Di dunia pengembangan backend modern, pengalaman pengguna yang mulus menjadi perhatian utama. Salah satu tantangan yang sering ditemui adalah bagaimana memberikan update progress secara real-time kepada user, terutama dalam proses backend yang memakan waktu cukup lama seperti parsing, konversi, atau import data besar.
Dalam artikel ini, kita akan membahas studi kasus implementasi Streaming Progress Update menggunakan gRPC Stream di Go (Golang). Kita akan bahas konsep arsitektur, kode implementasi server dan client, dan contoh simulasi dengan tabel serta diagram alur proses.
Permasalahan
Bayangkan sebuah aplikasi desktop atau web yang mengunggah file besar ke backend untuk diproses. Backend memerlukan waktu cukup lama, sementara user tidak diberi tahu progresnya. Hal ini menurunkan UX karena user tidak tahu apakah proses sedang berjalan atau gagal.
Solusi: Streaming Progress via gRPC
gRPC mendukung server-side streaming, memungkinkan server mengirim aliran data berkala ke client dalam satu koneksi gRPC. Ini sangat cocok untuk pengiriman progress update.
Diagram Arsitektur
flowchart LR Client -->|StartJob RPC| Server Server -->|Stream Progress| Client Server -->|Simulasi Proses| Processor
Struktur Proyek
progress-grpc/
├── proto/
│ └── progress.proto
├── server/
│ └── main.go
├── client/
│ └── main.go
1. Definisi Protobuf
proto/progress.proto
syntax = "proto3";
package progress;
service ProgressService {
rpc StartJob(JobRequest) returns (stream ProgressResponse);
}
message JobRequest {
string job_id = 1;
}
message ProgressResponse {
int32 percent = 1;
string message = 2;
}
Generate dengan:
protoc --go_out=. --go-grpc_out=. proto/progress.proto
2. Implementasi Server
server/main.go
package main
import (
"context"
"fmt"
"log"
"math/rand"
"net"
"time"
pb "progress-grpc/proto"
"google.golang.org/grpc"
)
type server struct {
pb.UnimplementedProgressServiceServer
}
func (s *server) StartJob(req *pb.JobRequest, stream pb.ProgressService_StartJobServer) error {
progress := 0
for progress < 100 {
time.Sleep(1 * time.Second)
step := rand.Intn(10) + 5
progress += step
if progress > 100 {
progress = 100
}
msg := fmt.Sprintf("Progress %d%%", progress)
stream.Send(&pb.ProgressResponse{
Percent: int32(progress),
Message: msg,
})
}
return nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterProgressServiceServer(s, &server{})
log.Println("gRPC server running on :50051")
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
3. Implementasi Client
client/main.go
package main
import (
"context"
"log"
"time"
pb "progress-grpc/proto"
"google.golang.org/grpc"
)
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewProgressServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
stream, err := client.StartJob(ctx, &pb.JobRequest{JobId: "abc123"})
if err != nil {
log.Fatalf("error calling StartJob: %v", err)
}
for {
msg, err := stream.Recv()
if err != nil {
log.Printf("stream ended: %v", err)
break
}
log.Printf("[%d%%] %s", msg.Percent, msg.Message)
}
}
Simulasi Output Progress
Berikut simulasi hasil output progress di console client:
[6%] Progress 6%
[13%] Progress 13%
[25%] Progress 25%
[39%] Progress 39%
[52%] Progress 52%
[66%] Progress 66%
[81%] Progress 81%
[95%] Progress 95%
[100%] Progress 100%
Tabel Perbandingan Pendekatan
Pendekatan | Kompatibilitas | Overhead | Responsif | Cocok untuk |
---|---|---|---|---|
Polling REST | Tinggi | Tinggi | Lambat | Task ringan |
Websocket | Menengah | Sedang | Cepat | Interaktif 2 arah |
SSE (EventStream) | Tinggi (HTTP) | Rendah | Sedang | Browser, 1 arah |
gRPC Stream | gRPC only | Rendah | Cepat | Internal RPC/Streaming |
Kesimpulan
Dengan memanfaatkan server-side streaming gRPC, kita bisa memberikan update progress secara efisien dan real-time. Pendekatan ini ideal untuk aplikasi internal berbasis microservice, CLI, atau desktop client yang terhubung ke backend berbasis Go.
Studi kasus di atas bisa dikembangkan lebih lanjut:
- Integrasi dengan Redis untuk status job multi-process.
- Middleware autentikasi gRPC.
- Penggunaan UUID atau tracing span untuk jobID.
Semoga studi kasus ini membantu kamu memahami cara menerapkan streaming update yang skalabel dan efektif. 🚀
8 Struktur Direktori Ideal untuk Proyek graphql-go
Artikel Terhangat
30 Studi Kasus: Streaming Progress Update
07 Jul 2025
29 Studi Kasus: Streaming Upload File
07 Jul 2025
28 Studi Kasus: Streaming Chat Sederhana
07 Jul 2025
6 Inisialisasi Proyek Go untuk GraphQL
07 Jul 2025

30 Studi Kasus: Streaming Progress Update

29 Studi Kasus: Streaming Upload File

28 Studi Kasus: Streaming Chat Sederhana
