Skip to content

Commit 922cf84

Browse files
add batch config, frame size validation
1 parent 51d92d7 commit 922cf84

5 files changed

Lines changed: 97 additions & 29 deletions

File tree

apps/kafkaesque_core/lib/kafkaesque/storage/single_file.ex

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,10 +648,20 @@ defmodule Kafkaesque.Storage.SingleFile do
648648
defp parse_frame_content(
649649
<<@magic_byte, crc::32, attr, timestamp::64, key_len::32, key::binary-size(key_len),
650650
val_len::32, value::binary-size(val_len), headers_len::16,
651-
headers_data::binary-size(headers_len), _rest::binary>>
651+
headers_data::binary-size(headers_len), rest::binary>> = frame_data
652652
) do
653-
# Validate sizes
653+
# Calculate expected frame size
654+
expected_size = 1 + 4 + 1 + 8 + 4 + key_len + 4 + val_len + 2 + headers_len
655+
actual_size = byte_size(frame_data)
656+
657+
# Validate frame size matches expected size
654658
cond do
659+
actual_size != expected_size ->
660+
{:error, :frame_size_mismatch}
661+
662+
byte_size(rest) != 0 ->
663+
{:error, :frame_has_trailing_data}
664+
655665
key_len > Constants.max_key_size() ->
656666
{:error, :key_too_large}
657667

apps/kafkaesque_core/lib/kafkaesque/topic/supervisor.ex

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ defmodule Kafkaesque.Topic.Supervisor do
2121
@doc """
2222
Creates a new topic with the specified number of partitions.
2323
"""
24-
def create_topic(name, partitions \\ 1) when is_binary(name) and partitions > 0 do
24+
def create_topic(name, partitions \\ 1, opts \\ []) when is_binary(name) and partitions > 0 do
2525
Logger.debug("Creating topic '#{name}' with #{partitions} partitions")
2626

2727
# Start supervisor for each partition
2828
results =
2929
Enum.map(0..(partitions - 1), fn partition ->
30-
start_partition(name, partition)
30+
start_partition(name, partition, opts)
3131
end)
3232

3333
# Check if all partitions started successfully
@@ -167,11 +167,11 @@ defmodule Kafkaesque.Topic.Supervisor do
167167
|> Enum.any?()
168168
end
169169

170-
defp start_partition(topic, partition) do
170+
defp start_partition(topic, partition, opts) do
171171
child_spec = %{
172172
id: {topic, partition},
173173
start:
174-
{__MODULE__.PartitionSupervisor, :start_link, [[topic: topic, partition: partition]]},
174+
{__MODULE__.PartitionSupervisor, :start_link, [Keyword.merge([topic: topic, partition: partition], opts)]},
175175
type: :supervisor,
176176
restart: :permanent
177177
}
@@ -237,10 +237,10 @@ defmodule Kafkaesque.Topic.Supervisor.PartitionSupervisor do
237237
[
238238
topic: topic,
239239
partition: partition,
240-
batch_size: Application.get_env(:kafkaesque_core, :max_batch_size, 500),
241-
batch_timeout: Application.get_env(:kafkaesque_core, :batch_timeout, 5000),
242-
min_demand: Application.get_env(:kafkaesque_core, :min_demand, 5),
243-
max_demand: Application.get_env(:kafkaesque_core, :max_batch_size, 500)
240+
batch_size: Keyword.get(opts, :batch_size, Application.get_env(:kafkaesque_core, :max_batch_size, 500)),
241+
batch_timeout: Keyword.get(opts, :batch_timeout, Application.get_env(:kafkaesque_core, :batch_timeout, 5000)),
242+
min_demand: Keyword.get(opts, :min_demand, Application.get_env(:kafkaesque_core, :min_demand, 5)),
243+
max_demand: Keyword.get(opts, :max_demand, Application.get_env(:kafkaesque_core, :max_batch_size, 500))
244244
]},
245245

246246
# Log reader for consuming
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
defmodule Kafkaesque.Topic.BatchConfigTest do
2+
use ExUnit.Case, async: false
3+
alias Kafkaesque.Topic.Supervisor, as: TopicSupervisor
4+
5+
setup do
6+
on_exit(fn ->
7+
# Clean up any test topics
8+
TopicSupervisor.list_topics()
9+
|> Enum.each(fn
10+
{topic, _} when is_binary(topic) ->
11+
if String.starts_with?(topic, "batch_config_test") do
12+
TopicSupervisor.delete_topic(topic)
13+
end
14+
%{name: topic} when is_binary(topic) ->
15+
if String.starts_with?(topic, "batch_config_test") do
16+
TopicSupervisor.delete_topic(topic)
17+
end
18+
_ ->
19+
:ok
20+
end)
21+
end)
22+
23+
:ok
24+
end
25+
26+
describe "per-topic batch configuration" do
27+
test "create_topic accepts batch configuration options" do
28+
topic = "batch_config_test_#{System.unique_integer([:positive])}"
29+
30+
# Create topic with custom batch settings
31+
opts = [
32+
batch_size: 100,
33+
batch_timeout: 1000,
34+
min_demand: 10,
35+
max_demand: 200
36+
]
37+
38+
assert {:ok, _} = TopicSupervisor.create_topic(topic, 1, opts)
39+
40+
# Verify the topic was created
41+
topics = TopicSupervisor.list_topics()
42+
assert Enum.any?(topics, fn
43+
{name, _} -> name == topic
44+
%{name: name} -> name == topic
45+
end)
46+
47+
# Get the BatchingConsumer process via Registry
48+
[{consumer_pid, _}] = Registry.lookup(Kafkaesque.TopicRegistry, {:batching_consumer, topic, 0})
49+
assert consumer_pid != nil
50+
51+
# Verify the BatchingConsumer state has the correct config
52+
gen_stage_state = :sys.get_state(consumer_pid)
53+
consumer_state = gen_stage_state.state
54+
assert consumer_state.batch_size == 100
55+
assert consumer_state.batch_timeout == 1000
56+
end
57+
58+
test "create_topic uses defaults when no options provided" do
59+
topic = "batch_config_test_default_#{System.unique_integer([:positive])}"
60+
61+
assert {:ok, _} = TopicSupervisor.create_topic(topic, 1)
62+
63+
# Get the BatchingConsumer process via Registry
64+
[{consumer_pid, _}] = Registry.lookup(Kafkaesque.TopicRegistry, {:batching_consumer, topic, 0})
65+
assert consumer_pid != nil
66+
67+
# Verify defaults are used
68+
gen_stage_state = :sys.get_state(consumer_pid)
69+
consumer_state = gen_stage_state.state
70+
default_batch_size = Application.get_env(:kafkaesque_core, :max_batch_size, 500)
71+
default_timeout = Application.get_env(:kafkaesque_core, :batch_timeout, 5000)
72+
73+
assert consumer_state.batch_size == default_batch_size
74+
assert consumer_state.batch_timeout == default_timeout
75+
end
76+
end
77+
end

apps/kafkaesque_proto/lib/kafkaesque_proto.ex

Lines changed: 0 additions & 18 deletions
This file was deleted.

apps/kafkaesque_proto/test/test_helper.exs

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)