19
19
20
20
import org .apache .eventmesh .storage .standalone .broker .model .MessageEntity ;
21
21
import org .apache .eventmesh .storage .standalone .broker .model .TopicMetadata ;
22
- import org .apache .eventmesh .storage .standalone .broker .task .HistoryMessageClear ;
23
- import org .apache .eventmesh .storage .standalone .broker .task .HistoryMessageClearTask ;
24
-
25
- import org .apache .commons .lang3 .tuple .Pair ;
22
+ import org .apache .eventmesh .storage .standalone .broker .task .Subscribe ;
26
23
27
24
import java .util .concurrent .ConcurrentHashMap ;
28
- import java .util .concurrent .atomic .AtomicLong ;
29
25
30
26
import io .cloudevents .CloudEvent ;
31
27
28
+ import lombok .Getter ;
29
+ import lombok .extern .slf4j .Slf4j ;
30
+
32
31
/**
33
32
* This broker used to store event, it just support standalone mode, you shouldn't use this module in production environment
34
33
*/
34
+ @ Slf4j
35
35
public class StandaloneBroker {
36
36
37
- private final ConcurrentHashMap <TopicMetadata , MessageQueue > messageContainer ;
37
+ // message source by topic
38
+ @ Getter
39
+ private final ConcurrentHashMap <TopicMetadata , Channel > messageContainer ;
38
40
39
- // todo: move the offset manage to consumer
40
- private final ConcurrentHashMap <TopicMetadata , AtomicLong > offsetMap ;
41
+ @ Getter
42
+ private final ConcurrentHashMap <TopicMetadata , Subscribe > subscribeContainer ;
41
43
42
44
private StandaloneBroker () {
43
45
this .messageContainer = new ConcurrentHashMap <>();
44
- this .offsetMap = new ConcurrentHashMap <>();
45
- startHistoryMessageCleanTask ();
46
- }
47
-
48
- public ConcurrentHashMap <TopicMetadata , MessageQueue > getMessageContainer () {
49
- return this .messageContainer ;
46
+ this .subscribeContainer = new ConcurrentHashMap <>();
50
47
}
51
48
52
- public ConcurrentHashMap <TopicMetadata , AtomicLong > getOffsetMap () {
53
- return this .offsetMap ;
54
- }
55
49
56
50
public static StandaloneBroker getInstance () {
57
- return StandaloneBrokerInstanceHolder .instance ;
51
+ return StandaloneBrokerInstanceHolder .INSTANCE ;
58
52
}
59
53
60
54
/**
61
55
* put message
62
56
*
63
57
* @param topicName topic name
64
58
* @param message message
65
- * @throws InterruptedException
66
59
*/
67
- public MessageEntity putMessage (String topicName , CloudEvent message ) throws InterruptedException {
68
- Pair <MessageQueue , AtomicLong > pair = createTopicIfAbsent (topicName );
69
- AtomicLong topicOffset = pair .getRight ();
70
- MessageQueue messageQueue = pair .getLeft ();
71
-
72
- MessageEntity messageEntity = new MessageEntity (
73
- new TopicMetadata (topicName ), message , topicOffset .getAndIncrement (), System .currentTimeMillis ());
74
- messageQueue .put (messageEntity );
75
-
60
+ public MessageEntity putMessage (String topicName , CloudEvent message ) {
61
+ TopicMetadata topicMetadata = new TopicMetadata (topicName );
62
+ if (!messageContainer .containsKey (topicMetadata )) {
63
+ createTopic (topicName );
64
+ }
65
+ Channel channel = messageContainer .get (topicMetadata );
66
+ MessageEntity messageEntity = new MessageEntity (new TopicMetadata (topicName ), message );
67
+ channel .getProvider ().onData (messageEntity );
76
68
return messageEntity ;
77
69
}
78
70
71
+ public Channel createTopic (String topicName ) {
72
+ TopicMetadata topicMetadata = new TopicMetadata (topicName );
73
+ return messageContainer .computeIfAbsent (topicMetadata , k -> {
74
+ Subscribe subscribe = subscribeContainer .get (topicMetadata );
75
+ if (subscribe == null ) {
76
+ throw new IllegalStateException ("the topic not exist subscribe " );
77
+ }
78
+ Channel channel = new Channel (topicMetadata , subscribe );
79
+ channel .start ();
80
+ return channel ;
81
+ });
82
+ }
83
+
79
84
/**
80
85
* Get the message, if the queue is empty then await
81
86
*
82
87
* @param topicName
83
88
*/
84
89
public CloudEvent takeMessage (String topicName ) throws InterruptedException {
85
- TopicMetadata topicMetadata = new TopicMetadata (topicName );
86
- return messageContainer .computeIfAbsent (topicMetadata , k -> new MessageQueue ()).take ().getMessage ();
90
+ return null ;
87
91
}
88
92
89
93
/**
@@ -92,12 +96,7 @@ public CloudEvent takeMessage(String topicName) throws InterruptedException {
92
96
* @param topicName
93
97
*/
94
98
public CloudEvent getMessage (String topicName ) {
95
- TopicMetadata topicMetadata = new TopicMetadata (topicName );
96
- MessageEntity head = messageContainer .computeIfAbsent (topicMetadata , k -> new MessageQueue ()).getHead ();
97
- if (head == null ) {
98
- return null ;
99
- }
100
- return head .getMessage ();
99
+ return null ;
101
100
}
102
101
103
102
/**
@@ -108,21 +107,9 @@ public CloudEvent getMessage(String topicName) {
108
107
* @return CloudEvent
109
108
*/
110
109
public CloudEvent getMessage (String topicName , long offset ) {
111
- TopicMetadata topicMetadata = new TopicMetadata (topicName );
112
- MessageEntity messageEntity = messageContainer .computeIfAbsent (topicMetadata , k -> new MessageQueue ()).getByOffset (offset );
113
- if (messageEntity == null ) {
114
- return null ;
115
- }
116
- return messageEntity .getMessage ();
110
+ return null ;
117
111
}
118
112
119
- private void startHistoryMessageCleanTask () {
120
- HistoryMessageClear historyMessageClear = new HistoryMessageClear (messageContainer );
121
- Thread thread = new Thread (new HistoryMessageClearTask (historyMessageClear ));
122
- thread .setDaemon (true );
123
- thread .setName ("StandaloneBroker-HistoryMessageCleanTask" );
124
- thread .start ();
125
- }
126
113
127
114
public boolean checkTopicExist (String topicName ) {
128
115
return messageContainer .containsKey (new TopicMetadata (topicName ));
@@ -132,13 +119,10 @@ public boolean checkTopicExist(String topicName) {
132
119
* if the topic does not exist, create the topic
133
120
*
134
121
* @param topicName topicName
135
- * @return messageQueue and offset
122
+ * @return Channel
136
123
*/
137
- public Pair <MessageQueue , AtomicLong > createTopicIfAbsent (String topicName ) {
138
- TopicMetadata topicMetadata = new TopicMetadata (topicName );
139
- MessageQueue messageQueue = messageContainer .computeIfAbsent (topicMetadata , k -> new MessageQueue ());
140
- AtomicLong offset = offsetMap .computeIfAbsent (topicMetadata , k -> new AtomicLong ());
141
- return Pair .of (messageQueue , offset );
124
+ public Channel createTopicIfAbsent (String topicName ) {
125
+ return createTopic (topicName );
142
126
}
143
127
144
128
/**
@@ -148,18 +132,23 @@ public Pair<MessageQueue, AtomicLong> createTopicIfAbsent(String topicName) {
148
132
*/
149
133
public void deleteTopicIfExist (String topicName ) {
150
134
TopicMetadata topicMetadata = new TopicMetadata (topicName );
135
+ Channel channel = createTopicIfAbsent (topicName );
136
+ channel .shutdown ();
151
137
messageContainer .remove (topicMetadata );
152
138
}
153
139
154
- public void updateOffset (TopicMetadata topicMetadata , long offset ) {
155
- offsetMap .computeIfPresent (topicMetadata , (k , v ) -> {
156
- v .set (offset );
157
- return v ;
158
- });
140
+ public void subscribed (String topicName , Subscribe subscribe ) {
141
+ TopicMetadata topicMetadata = new TopicMetadata (topicName );
142
+ if (getMessageContainer ().containsKey (topicMetadata )) {
143
+ log .warn ("the topic already subscribed" );
144
+ return ;
145
+ }
146
+ subscribeContainer .put (topicMetadata , subscribe );
159
147
}
160
148
149
+
161
150
private static class StandaloneBrokerInstanceHolder {
162
151
163
- private static final StandaloneBroker instance = new StandaloneBroker ();
152
+ private static final StandaloneBroker INSTANCE = new StandaloneBroker ();
164
153
}
165
- }
154
+ }
0 commit comments