keycloak
クラス | 公開メンバ関数 | 非公開メンバ関数 | 非公開変数類 | 静的非公開変数類 | 全メンバ一覧
org.keycloak.models.sessions.infinispan.remotestore.ClientListenerExecutorDecorator< K > クラステンプレート
org.keycloak.models.sessions.infinispan.remotestore.ClientListenerExecutorDecorator< K > 連携図
Collaboration graph

クラス

class  MyClientEvent
 
class  MyClientEventContext
 

公開メンバ関数

 ClientListenerExecutorDecorator (ExecutorService decorated)
 
void submit (ClientCacheEntryCreatedEvent< K > cacheEntryCreatedEvent, Runnable r)
 
void submit (ClientCacheEntryModifiedEvent< K > cacheEntryModifiedEvent, Runnable r)
 
void submit (ClientCacheEntryRemovedEvent< K > cacheEntryRemovedEvent, Runnable r)
 
MyClientEvent convertIspnClientEvent (ClientEvent ispnClientEvent)
 

非公開メンバ関数

void submit (MyClientEvent event, Runnable r)
 
void submitImpl (K key, MyClientEvent event, Runnable r)
 
void pollQueue (K key)
 
void putEventToTheQueue (K key, MyClientEvent event, Runnable r)
 

非公開変数類

final Object lock = new Object()
 
final ExecutorService decorated
 
Map< K, MyClientEventeventsInProgress = new HashMap<>()
 
MultivaluedHashMap< K, MyClientEventContexteventsQueue = new MultivaluedHashMap<>()
 

静的非公開変数類

static final Logger logger = Logger.getLogger(ClientListenerExecutorDecorator.class)
 

詳解

著者
Marek Posolda

構築子と解体子

◆ ClientListenerExecutorDecorator()

57  {
58  this.decorated = decorated;
59  }
final ExecutorService decorated
Definition: ClientListenerExecutorDecorator.java:46

関数詳解

◆ convertIspnClientEvent()

MyClientEvent org.keycloak.models.sessions.infinispan.remotestore.ClientListenerExecutorDecorator< K >.convertIspnClientEvent ( ClientEvent  ispnClientEvent)
inline
232  {
233  if (ispnClientEvent instanceof ClientCacheEntryCreatedEvent) {
234  ClientCacheEntryCreatedEvent<K> ev = (ClientCacheEntryCreatedEvent<K>) ispnClientEvent;
235  return new MyClientEvent(ev.getKey(), ev.getVersion(), ev.getType());
236  } else if (ispnClientEvent instanceof ClientCacheEntryModifiedEvent) {
237  ClientCacheEntryModifiedEvent<K> ev = (ClientCacheEntryModifiedEvent<K>) ispnClientEvent;
238  return new MyClientEvent(ev.getKey(), ev.getVersion(), ev.getType());
239  } else if (ispnClientEvent instanceof ClientCacheEntryRemovedEvent) {
240  ClientCacheEntryRemovedEvent<K> ev = (ClientCacheEntryRemovedEvent<K>) ispnClientEvent;
241  return new MyClientEvent(ev.getKey(), -1l, ev.getType());
242  } else {
243  throw new IllegalStateException("Unsupported event type: " + ispnClientEvent.getType());
244  }
245  }

◆ pollQueue()

137  {
138  if (eventsQueue.containsKey(key)) {
139  List<MyClientEventContext> events = eventsQueue.get(key);
140 
141  if (events.size() > 0) {
142  MyClientEventContext nextEvent = events.remove(0);
143 
144  // Was last event in the queue for that key
145  if (events.size() == 0) {
146  eventsQueue.remove(key);
147  }
148 
149  submitImpl(key, nextEvent.event, nextEvent.r);
150 
151  } else {
152  // Shouldn't happen
153  throw new IllegalStateException("Illegal state. Size was 0 for key " + key);
154  }
155  }
156  }
MultivaluedHashMap< K, MyClientEventContext > eventsQueue
Definition: ClientListenerExecutorDecorator.java:54
void submitImpl(K key, MyClientEvent event, Runnable r)
Definition: ClientListenerExecutorDecorator.java:98

◆ putEventToTheQueue()

void org.keycloak.models.sessions.infinispan.remotestore.ClientListenerExecutorDecorator< K >.putEventToTheQueue ( key,
MyClientEvent  event,
Runnable  r 
)
inlineprivate
160  {
161  logger.debugf("Calling putEventToTheQueue: %s", event.toString());
162 
163  if (!eventsQueue.containsKey(key)) {
164  eventsQueue.putSingle(key, new MyClientEventContext(event, r));
165  } else {
166 
167  List<MyClientEventContext> existingEvents = eventsQueue.get(key);
168  MyClientEventContext myNewEvent = new MyClientEventContext(event, r);
169 
170  // Try to optimize queue (EG. in case we have REMOVE event, we can ignore the previous CREATE or MODIFIED events)
171  switch (event.type) {
172  case CLIENT_CACHE_ENTRY_CREATED:
173  boolean add = true;
174  for (MyClientEventContext ctx : existingEvents) {
175  if (ctx.event.type == CLIENT_CACHE_ENTRY_REMOVED) {
176  // Ignore. TODO: Log me?
177  add = false;
178  break;
179  } else if (ctx.event.type == CLIENT_CACHE_ENTRY_CREATED) {
180  // Ignore. Already on the list
181  add = false;
182  break;
183  }
184  }
185 
186  // Add to the beginning before the MODIFIED events
187  if (add) {
188  existingEvents.add(0, myNewEvent);
189  }
190  break;
191  case CLIENT_CACHE_ENTRY_MODIFIED:
192 
193  boolean addd = true;
194  for (int i=0 ; i<existingEvents.size() ; i++) {
195  MyClientEventContext ctx = existingEvents.get(i);
196  if (ctx.event.type == CLIENT_CACHE_ENTRY_REMOVED) {
197  // Ignore.
198  addd = false;
199  break;
200  } else if (ctx.event.type == CLIENT_CACHE_ENTRY_CREATED) {
201  // Shift to the next element. CREATE event go first.
202  } else {
203  // Can ignore the previous MODIFY event if we have newer version
204  if (ctx.event.version < myNewEvent.event.version) {
205  existingEvents.remove(i);
206  } else {
207  addd = false;
208  }
209  }
210 
211  if (addd) {
212  // Add to the end
213  existingEvents.add(myNewEvent);
214  }
215  }
216  break;
217 
218  case CLIENT_CACHE_ENTRY_REMOVED:
219  // Can just ignore the other events in the queue in case of REMOVE
220  eventsQueue.putSingle(key, new MyClientEventContext(event, r));
221  break;
222  default:
223  throw new IllegalStateException("Unsupported event type: " + event.type);
224  }
225 
226  }
227 
228  logger.debugf("Event queued. Current events for the key '%s': %s", key.toString(), eventsQueue.getList(key));
229  }
static final Logger logger
Definition: ClientListenerExecutorDecorator.java:42
MultivaluedHashMap< K, MyClientEventContext > eventsQueue
Definition: ClientListenerExecutorDecorator.java:54

◆ submit() [1/4]

void org.keycloak.models.sessions.infinispan.remotestore.ClientListenerExecutorDecorator< K >.submit ( ClientCacheEntryCreatedEvent< K >  cacheEntryCreatedEvent,
Runnable  r 
)
inline
64  {
65  MyClientEvent event = convertIspnClientEvent(cacheEntryCreatedEvent);
66  submit(event, r);
67  }
void submit(ClientCacheEntryCreatedEvent< K > cacheEntryCreatedEvent, Runnable r)
Definition: ClientListenerExecutorDecorator.java:64
MyClientEvent convertIspnClientEvent(ClientEvent ispnClientEvent)
Definition: ClientListenerExecutorDecorator.java:232

◆ submit() [2/4]

void org.keycloak.models.sessions.infinispan.remotestore.ClientListenerExecutorDecorator< K >.submit ( ClientCacheEntryModifiedEvent< K >  cacheEntryModifiedEvent,
Runnable  r 
)
inline
70  {
71  MyClientEvent event = convertIspnClientEvent(cacheEntryModifiedEvent);
72  submit(event, r);
73  }
void submit(ClientCacheEntryCreatedEvent< K > cacheEntryCreatedEvent, Runnable r)
Definition: ClientListenerExecutorDecorator.java:64
MyClientEvent convertIspnClientEvent(ClientEvent ispnClientEvent)
Definition: ClientListenerExecutorDecorator.java:232

◆ submit() [3/4]

void org.keycloak.models.sessions.infinispan.remotestore.ClientListenerExecutorDecorator< K >.submit ( ClientCacheEntryRemovedEvent< K >  cacheEntryRemovedEvent,
Runnable  r 
)
inline
76  {
77  MyClientEvent event = convertIspnClientEvent(cacheEntryRemovedEvent);
78  submit(event, r);
79  }
void submit(ClientCacheEntryCreatedEvent< K > cacheEntryCreatedEvent, Runnable r)
Definition: ClientListenerExecutorDecorator.java:64
MyClientEvent convertIspnClientEvent(ClientEvent ispnClientEvent)
Definition: ClientListenerExecutorDecorator.java:232

◆ submit() [4/4]

84  {
85  K key = event.key;
86 
87  synchronized (lock) {
88  if (!eventsInProgress.containsKey(key)) {
89  submitImpl(key, event, r);
90  } else {
91  putEventToTheQueue(key, event, r);
92  }
93  }
94  }
final Object lock
Definition: ClientListenerExecutorDecorator.java:44
Map< K, MyClientEvent > eventsInProgress
Definition: ClientListenerExecutorDecorator.java:51
void putEventToTheQueue(K key, MyClientEvent event, Runnable r)
Definition: ClientListenerExecutorDecorator.java:160
void submitImpl(K key, MyClientEvent event, Runnable r)
Definition: ClientListenerExecutorDecorator.java:98

◆ submitImpl()

void org.keycloak.models.sessions.infinispan.remotestore.ClientListenerExecutorDecorator< K >.submitImpl ( key,
MyClientEvent  event,
Runnable  r 
)
inlineprivate
98  {
99  logger.debugf("Submitting event to the executor: %s . eventsInProgress size: %d, eventsQueue size: %d", event.toString(), eventsInProgress.size(), eventsQueue.size());
100 
101  eventsInProgress.put(key, event);
102 
103  Runnable decoratedRunnable = () -> {
104  Long start = null;
105  try {
106  if (logger.isDebugEnabled()) {
107  start = Time.currentTimeMillis();
108  }
109 
110  r.run();
111  } finally {
112  synchronized (lock) {
113  eventsInProgress.remove(key);
114 
115  if (logger.isDebugEnabled()) {
116  long took = Time.currentTimeMillis() - start;
117  logger.debugf("Finished processing event by the executor: %s, took: %d ms. EventsInProgress size: %d", event.toString(), took, eventsInProgress.size());
118  }
119 
120  pollQueue(key);
121  }
122  }
123  };
124 
125  try {
126  decorated.submit(decoratedRunnable);
127  } catch (RejectedExecutionException ree) {
128  eventsInProgress.remove(key);
129 
130  logger.errorf("Rejected execution of task for the event '%s' . Try to increase the pool size. Pool is '%s'", event.toString(), decorated.toString());
131  throw ree;
132  }
133  }
static final Logger logger
Definition: ClientListenerExecutorDecorator.java:42
final Object lock
Definition: ClientListenerExecutorDecorator.java:44
final ExecutorService decorated
Definition: ClientListenerExecutorDecorator.java:46
MultivaluedHashMap< K, MyClientEventContext > eventsQueue
Definition: ClientListenerExecutorDecorator.java:54
Map< K, MyClientEvent > eventsInProgress
Definition: ClientListenerExecutorDecorator.java:51
void pollQueue(K key)
Definition: ClientListenerExecutorDecorator.java:137

メンバ詳解

◆ decorated

◆ eventsInProgress

◆ eventsQueue

◆ lock

◆ logger

final Logger org.keycloak.models.sessions.infinispan.remotestore.ClientListenerExecutorDecorator< K >.logger = Logger.getLogger(ClientListenerExecutorDecorator.class)
staticprivate

このクラス詳解は次のファイルから抽出されました: