View Javadoc
1   /*
2    * Copyright (C) 2012-2024 RRiBbit.org
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.rribbit.execution;
17  
18  import java.util.Collection;
19  import java.util.Collections;
20  import java.util.stream.Collectors;
21  
22  import org.rribbit.ListenerObject;
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  
26  /**
27   * This {@link AbstractListenerObjectExecutor} executes the {@link ListenerObject}s in parallel {@link Thread}s. If there is only one {@link ListenerObject} to be executed, then
28   * it will be executed in the calling {@link Thread} and no new {@link Thread} will be created.
29   *
30   * Please note that spawning new {@link Thread}s to execute the {@link ListenerObject}s will result in the loss of the transaction context. If the transaction context must be preserved,
31   * either make sure that only a single {@link ListenerObject} is executed or consider using the {@link SequentialListenerObjectExecutor}.
32   *
33   * @author G.J. Schouten
34   *
35   */
36  public class MultiThreadedListenerObjectExecutor extends AbstractListenerObjectExecutor {
37  
38  	private static final Logger log = LoggerFactory.getLogger(MultiThreadedListenerObjectExecutor.class);
39  
40  	@Override
41  	protected Collection<ExecutionResult> doExecuteListeners(Collection<ListenerObject> listenerObjects, Object... parameters) {
42  
43  		if(listenerObjects.isEmpty()) {
44  			log.debug("No ListenerObjects to process");
45  			return Collections.emptyList();
46  		} else if(listenerObjects.size() == 1) { //There is only one, don't spawn a new Thread, but do it in this Thread
47  			log.debug("There is only one ListenerObject, not creating new Thread, executing it in this Thread");
48  			return Collections.singletonList(this.executeSingleListenerObject(listenerObjects.iterator().next(), parameters));
49  		}
50  
51  		log.debug("Creating Threads for each ListenerObject and executing");
52  		return listenerObjects
53  			.stream()
54  			.parallel()
55  			.map(listenerObject -> this.executeSingleListenerObject(listenerObject, parameters))
56  			.collect(Collectors.toList());
57  	}
58  }