moved the kafka-go project to this repository

This commit is contained in:
Timmelmann
2026-08-08 14:26:06 +02:00
commit 58710c23b2
11 changed files with 225 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
[![progress-banner](https://backend.codecrafters.io/progress/kafka/4eddd9dd-43a3-4d8f-bae7-2f6d7d8ec6bc)](https://app.codecrafters.io/users/Timmelmann?r=2qF)
This is a starting point for Go solutions to the
["Build Your Own Kafka" Challenge](https://codecrafters.io/challenges/kafka).
In this challenge, you'll build a toy Kafka clone that's capable of accepting
and responding to APIVersions & Fetch API requests. You'll also learn about
encoding and decoding messages using the Kafka wire protocol. You'll also learn
about handling the network protocol, event loops, TCP sockets and more.
**Note**: If you're viewing this repo on GitHub, head over to
[codecrafters.io](https://codecrafters.io) to try the challenge.
# Passing the first stage
The entry point for your Kafka implementation is in `app/server.go`. Study and
uncomment the relevant code, and push your changes to pass the first stage:
```sh
git commit -am "pass 1st stage" # any msg
git push origin master
```
That's all!
# Stage 2 & beyond
Note: This section is for stages 2 and beyond.
1. Ensure you have `go (1.19)` installed locally
1. Run `./your_program.sh` to run your Kafka broker, which is implemented in
`app/server.go`.
1. Commit your changes and run `git push origin master` to submit your solution
to CodeCrafters. Test output will be streamed to your terminal.
+35
View File
@@ -0,0 +1,35 @@
package protocol
import "encoding/binary"
type Request struct {
bytes []byte
byteParseOffset uint
Length int32
Header *RequestHeader
}
func NewRequest(bytes []byte) *Request {
req := Request{
bytes: bytes,
byteParseOffset: 0,
}
req.Length = req.ReadInt32()
req.Header = ParseRequestHeader(&req)
return &req
}
func (r *Request) ReadInt16() int16{
val := binary.BigEndian.Uint16(r.bytes[r.byteParseOffset:])
r.byteParseOffset += 2
return int16(val)
}
func (r *Request) ReadInt32() int32 {
val := binary.BigEndian.Uint32(r.bytes[r.byteParseOffset:])
r.byteParseOffset += 4
return int32(val)
}
+19
View File
@@ -0,0 +1,19 @@
package protocol
type RequestHeader struct {
APIKey int16
APIVersion int16
Correlation_id int32
}
func ParseRequestHeader(r *Request) *RequestHeader {
apiKey := r.ReadInt16()
apiVersion := r.ReadInt16()
correlation_id := r.ReadInt32()
return &RequestHeader{
APIKey: apiKey,
APIVersion: apiVersion,
Correlation_id: correlation_id,
}
}
+7
View File
@@ -0,0 +1,7 @@
package response
type Message struct {
body []byte
header V0Header
messageSize int32
}
+19
View File
@@ -0,0 +1,19 @@
package response
import "encoding/binary"
type V0Header struct {
Correlation_id uint32
}
func NewHeader(correlation_id uint32) *V0Header {
return &V0Header{
Correlation_id: correlation_id,
}
}
func (h *V0Header) ToBytes() []byte {
buf := make([]byte, 4)
binary.BigEndian.PutUint32(buf, uint32(h.Correlation_id))
return buf
}
+28
View File
@@ -0,0 +1,28 @@
package response
import (
"encoding/binary"
)
type V0Response struct {
header V0Header
body []byte
}
func NewV0Reponse(correlation_id uint32) *V0Response {
return &V0Response{
header: V0Header{
Correlation_id: correlation_id},
body: []byte{},
}
}
func (r *V0Response) ToBytes() []byte {
header := r.header.ToBytes()
length := len(header)
buf := make([]byte, length+4)
binary.BigEndian.PutUint32(buf[0:4], uint32(length))
copy(buf[4:], header)
return buf
}
+37
View File
@@ -0,0 +1,37 @@
package main
import (
"fmt"
"net"
"os"
protocol "github.com/codecrafters-io/redis-starter-go/app/protocol/response"
)
// Ensures gofmt doesn't remove the "net" and "os" imports in stage 1 (feel free to remove this!)
var _ = net.Listen
var _ = os.Exit
func main() {
l, err := net.Listen("tcp", "0.0.0.0:9092")
if err != nil {
fmt.Println("Failed to bind to port 9092: ", err.Error())
os.Exit(1)
}
conn, err := l.Accept()
if err != nil {
fmt.Println("Could not accept connection: ", err.Error())
os.Exit(1)
}
defer conn.Close()
if _, err = conn.Read(make([]byte, 1024)); err != nil {
fmt.Println("Failed to read request: ", err.Error())
}
response := protocol.NewV0Reponse(7)
if _, err = conn.Write(response.ToBytes()); err != nil {
fmt.Println("Failed to write response: ", err.Error())
}
}
+11
View File
@@ -0,0 +1,11 @@
# Set this to true if you want debug logs.
#
# These can be VERY verbose, so we suggest turning them off
# unless you really need them.
debug: false
# Use this to change the Go version used to run your code
# on Codecrafters.
#
# Available versions: go-1.22
language_pack: go-1.22
+11
View File
@@ -0,0 +1,11 @@
// DON'T EDIT THIS!
//
// Codecrafters relies on this file being intact to run tests successfully. Any changes
// here will not reflect when CodeCrafters tests your code, and might even cause build
// failures.
//
// DON'T EDIT THIS!
module github.com/codecrafters-io/redis-starter-go
go 1.22
View File
+24
View File
@@ -0,0 +1,24 @@
#!/bin/sh
#
# Use this script to run your program LOCALLY.
#
# Note: Changing this script WILL NOT affect how CodeCrafters runs your program.
#
# Learn more: https://codecrafters.io/program-interface
set -e # Exit early if any commands fail
# Copied from .codecrafters/compile.sh
#
# - Edit this to change how your program compiles locally
# - Edit .codecrafters/compile.sh to change how your program compiles remotely
(
cd "$(dirname "$0")" # Ensure compile steps are run within the repository directory
go build -o /tmp/codecrafters-build-redis-go app/*.go
)
# Copied from .codecrafters/run.sh
#
# - Edit this to change how your program runs locally
# - Edit .codecrafters/run.sh to change how your program runs remotely
exec /tmp/codecrafters-build-redis-go "$@"