moved the kafka-go project to this repository
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
[](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.
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package response
|
||||
|
||||
type Message struct {
|
||||
body []byte
|
||||
header V0Header
|
||||
messageSize int32
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
Executable
+24
@@ -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 "$@"
|
||||
Reference in New Issue
Block a user