001/*
002 *  Copyright 2025 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.cms.indexing.solr;
017
018import java.util.concurrent.ExecutorService;
019import java.util.concurrent.Executors;
020import java.util.concurrent.Future;
021import java.util.concurrent.ThreadFactory;
022import java.util.concurrent.atomic.AtomicLong;
023
024import org.apache.avalon.framework.activity.Initializable;
025import org.apache.avalon.framework.component.Component;
026
027import org.ametys.plugins.repository.AmetysObject;
028
029/**
030 * Helper to submit thread needed for indexation.
031 */
032public class ThreadIndexerHelper implements Initializable, Component
033{
034    /** The Avalon Role */
035    public static final String ROLE = ThreadIndexerHelper.class.getName();
036    
037    private static ExecutorService __THREAD_EXECUTOR;
038    
039    public void initialize() throws Exception
040    {
041        ThreadFactory threadFactory = new SolrThreadFactory();
042        __THREAD_EXECUTOR = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() / 2, threadFactory);
043    }
044    
045    /**
046     * Submit an {@link AbstractIndexerCallable} to the executor dedicated to indexation.
047     * @param callable The callable to submit
048     * @return The {@link Future} from the {@link AbstractIndexerCallable} submission
049     */
050    public Future<Void> submitCallable(AbstractIndexerCallable<? extends AmetysObject> callable)
051    {
052        return __THREAD_EXECUTOR.submit(callable);
053    }
054
055    /**
056     * Thread factory for Solr indexation.
057     */
058    static class SolrThreadFactory implements ThreadFactory
059    {
060        private ThreadFactory _defaultThreadFactory;
061        private String _nameFormat;
062        private AtomicLong _count;
063        
064        public SolrThreadFactory()
065        {
066            _defaultThreadFactory = Executors.defaultThreadFactory();
067            _nameFormat = "ametys-solr-indexer-%d";
068            _count = new AtomicLong(0);
069        }
070        
071        public Thread newThread(Runnable r)
072        {
073            Thread thread = _defaultThreadFactory.newThread(r);
074            thread.setName(String.format(_nameFormat, _count.getAndIncrement()));
075            thread.setDaemon(true);
076            return thread;
077        }
078    }
079}