2
2
3
3
namespace Ensi \LaravelPhpRdKafkaConsumer \Commands ;
4
4
5
- use Ensi \LaravelPhpRdKafka \KafkaFacade ;
6
- use Ensi \LaravelPhpRdKafkaConsumer \ConsumerOptions ;
7
- use Ensi \LaravelPhpRdKafkaConsumer \HighLevelConsumer ;
8
- use Ensi \LaravelPhpRdKafkaConsumer \ProcessorData ;
5
+ use Ensi \LaravelPhpRdKafkaConsumer \Consumers \Consumer ;
6
+ use Ensi \LaravelPhpRdKafkaConsumer \Consumers \Factories \ConsumerFactory ;
7
+ use Ensi \LaravelPhpRdKafkaConsumer \Exceptions \KafkaConsumerException ;
8
+ use Ensi \LaravelPhpRdKafkaConsumer \Exceptions \KafkaConsumerProcessorException ;
9
+ use Ensi \LaravelPhpRdKafkaConsumer \Loggers \ConsumerLoggerFactory ;
10
+ use Ensi \LaravelPhpRdKafkaConsumer \Loggers \ConsumerLoggerInterface ;
9
11
use Illuminate \Console \Command ;
10
12
use Symfony \Component \Console \Command \SignalableCommandInterface ;
11
13
use Throwable ;
@@ -28,7 +30,12 @@ class KafkaConsumeCommand extends Command implements SignalableCommandInterface
28
30
*/
29
31
protected $ description = 'Consume concrete topic ' ;
30
32
31
- protected ?HighLevelConsumer $ consumer = null ;
33
+ protected ?Consumer $ consumer = null ;
34
+
35
+ public function __construct (protected ConsumerLoggerFactory $ loggerFactory )
36
+ {
37
+ parent ::__construct ();
38
+ }
32
39
33
40
public function getStopSignalsFromConfig (): array
34
41
{
@@ -40,6 +47,26 @@ public function getSubscribedSignals(): array
40
47
return $ this ->getStopSignalsFromConfig ();
41
48
}
42
49
50
+ public function getTopicKey (): string
51
+ {
52
+ return $ this ->argument ('topic-key ' );
53
+ }
54
+
55
+ public function getConsumerName (): string
56
+ {
57
+ return $ this ->argument ('consumer ' );
58
+ }
59
+
60
+ public function getMaxEvents (): int
61
+ {
62
+ return $ this ->option ('once ' ) ? 1 : (int ) $ this ->option ('max-events ' );
63
+ }
64
+
65
+ public function getMaxTime (): int
66
+ {
67
+ return (int ) $ this ->option ('max-time ' );
68
+ }
69
+
43
70
public function handleSignal (int $ signal , int |false $ previousExitCode = 0 ): int |false
44
71
{
45
72
if ($ this ->consumer ) {
@@ -53,84 +80,49 @@ public function handleSignal(int $signal, int|false $previousExitCode = 0): int|
53
80
/**
54
81
* Execute the console command.
55
82
*/
56
- public function handle (HighLevelConsumer $ highLevelConsumer ): int
83
+ public function handle (ConsumerFactory $ consumerFactory ): int
57
84
{
58
- $ this ->consumer = $ highLevelConsumer ;
59
- $ topicKey = $ this ->argument ('topic-key ' );
60
- $ consumer = $ this ->argument ('consumer ' );
61
-
62
- $ processorData = $ this ->findMatchedProcessor ($ topicKey , $ consumer );
63
- if (is_null ($ processorData )) {
64
- $ this ->error ("Processor for topic-key \"$ topicKey \" and consumer \"$ consumer \" is not found " );
65
- $ this ->line ('Processors are set in /config/kafka-consumer.php ' );
66
-
67
- return 1 ;
68
- }
69
-
70
- if (!class_exists ($ processorData ->class )) {
71
- $ this ->error ("Processor class \"$ processorData ->class \" is not found " );
72
- $ this ->line ('Processors are set in /config/kafka-consumer.php ' );
73
-
74
- return 1 ;
75
- }
76
-
77
- if (!$ processorData ->hasValidType ()) {
78
- $ this ->error ("Invalid processor type \"$ processorData ->type \", supported types are: " . implode (', ' , $ processorData ->getSupportedTypes ()));
79
-
80
- return 1 ;
81
- }
82
-
83
- $ consumerPackageOptions = config ('kafka-consumer.consumer_options. ' . $ consumer , []);
84
- $ consumerOptions = new ConsumerOptions (
85
- consumeTimeout: $ consumerPackageOptions ['consume_timeout ' ] ?? $ processorData ->consumeTimeout ,
86
- maxEvents: $ this ->option ('once ' ) ? 1 : (int ) $ this ->option ('max-events ' ),
87
- maxTime: (int ) $ this ->option ('max-time ' ),
88
- middleware: $ this ->collectMiddleware ($ consumerPackageOptions ['middleware ' ] ?? []),
89
- );
85
+ try {
86
+ $ this ->consumer = $ consumerFactory
87
+ ->build ($ this ->getTopicKey (), $ this ->getConsumerName ())
88
+ ->setMaxEvents ($ this ->getMaxEvents ())
89
+ ->setMaxTime ($ this ->getMaxTime ());
90
90
91
- $ topicName = KafkaFacade:: topicNameByClient ( ' consumer ' , $ consumer , $ topicKey );
92
- $ this -> info ( " Start listening to topic: \"{ $ topicKey }\" ( {$ topicName }), consumer \"{$ consumer }\"" );
91
+ $ this -> info ( " Start listening to topic: \"{ $ this -> getTopicKey ()}\"" .
92
+ " ( {$ this -> consumer -> getTopicName () }), consumer \"{$ this -> getConsumerName () }\"" );
93
93
94
- try {
95
- $ highLevelConsumer
96
- ->for ($ consumer )
97
- ->listen ($ topicName , $ processorData , $ consumerOptions );
98
- } catch (Throwable $ e ) {
99
- $ this ->error ('An error occurred while listening to the topic: ' . $ e ->getMessage () . ' ' . $ e ->getFile () . ':: ' . $ e ->getLine ());
94
+ $ this ->consumer ->listen ();
95
+ } catch (Throwable $ exception ) {
96
+ $ this ->errorThrowable ($ exception );
100
97
101
- return 1 ;
98
+ return self :: FAILURE ;
102
99
}
103
100
104
- return 0 ;
101
+ return self :: SUCCESS ;
105
102
}
106
103
107
- protected function findMatchedProcessor ( string $ topic , string $ consumer ): ? ProcessorData
104
+ private function errorThrowable ( Throwable $ exception ): void
108
105
{
109
- foreach (config ('kafka-consumer.processors ' , []) as $ processor ) {
110
- $ topicMatched = empty ($ processor ['topic ' ]) || $ processor ['topic ' ] === $ topic ;
111
- $ consumerMatched = empty ($ processor ['consumer ' ]) || $ processor ['consumer ' ] === $ consumer ;
112
- if ($ topicMatched && $ consumerMatched ) {
113
- return new ProcessorData (
114
- class: $ processor ['class ' ],
115
- topicKey: $ processor ['topic ' ] ?? null ,
116
- consumer: $ processor ['consumer ' ] ?? null ,
117
- type: $ processor ['type ' ] ?? 'action ' ,
118
- queue: $ processor ['queue ' ] ?? false ,
119
- consumeTimeout: $ processor ['consume_timeout ' ] ?? 20000 ,
120
- );
106
+ $ this ->makeLogger ()
107
+ ->error ($ exception ->getMessage (), ['exception ' => $ exception ]);
108
+
109
+ if ($ exception instanceof KafkaConsumerException) {
110
+ $ this ->error ($ exception ->getMessage ());
111
+
112
+ if ($ exception instanceof KafkaConsumerProcessorException) {
113
+ $ this ->line ('Processors are set in /config/kafka-consumer.php ' );
121
114
}
115
+
116
+ return ;
122
117
}
123
118
124
- return null ;
119
+ $ this ->error ('An error occurred while listening to the topic: ' .
120
+ $ exception ->getMessage () . ' ' . $ exception ->getFile () . ':: ' . $ exception ->getLine ());
125
121
}
126
122
127
- protected function collectMiddleware ( array $ processorMiddleware ): array
123
+ private function makeLogger ( ): ConsumerLoggerInterface
128
124
{
129
- return array_unique (
130
- array_merge (
131
- config ('kafka-consumer.global_middleware ' , []),
132
- $ processorMiddleware
133
- )
134
- );
125
+ return $ this ->loggerFactory
126
+ ->make ($ this ->getTopicKey (), $ this ->getConsumerName ());
135
127
}
136
128
}
0 commit comments