• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kermitt2 / grobid / 388

pending completion
388

push

circleci

update logs

3 of 3 new or added lines in 2 files covered. (100.0%)

14846 of 37503 relevant lines covered (39.59%)

0.4 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/grobid-core/src/main/java/org/grobid/core/utilities/glutton/GluttonClient.java
1
package org.grobid.core.utilities.glutton;
2

3
import java.io.IOException;
4
import java.net.URISyntaxException;
5
import java.util.Map;
6
import java.util.List;
7
import java.util.ArrayList;
8
import java.util.concurrent.Executors;
9
import java.util.concurrent.Future;
10

11
import org.apache.http.client.ClientProtocolException;
12
import org.grobid.core.utilities.crossref.*;
13
import org.slf4j.Logger;
14
import org.slf4j.LoggerFactory;
15

16
/**
17
 * Client to the Glutton bibliographical service
18
 *
19
 */
20
public class GluttonClient extends CrossrefClient {
21
    public static final Logger LOGGER = LoggerFactory.getLogger(GluttonClient.class);
×
22
    
23
    private static volatile GluttonClient instance;
24

25
    //private volatile ExecutorService executorService;
26
        
27
    //private static boolean limitAuto = true;
28
    //private volatile TimedSemaphore timedSemaphore;
29

30
    // this list is used to maintain a list of Futures that were submitted,
31
    // that we can use to check if the requests are completed
32
    //private volatile Map<Long, List<Future<?>>> futures = new HashMap<>();
33

34
    public static GluttonClient getInstance() {
35
        if (instance == null) {
×
36
            getNewInstance();
×
37
        }
38
        return instance;
×
39
    }
40

41
    /**
42
     * Creates a new instance.
43
     */
44
    private static synchronized void getNewInstance() {
45
        LOGGER.debug("Get new instance of GluttonClient");
×
46
        instance = new GluttonClient();
×
47
    }
×
48

49
    /**
50
     * Hidden constructor
51
     */
52
    private GluttonClient() {
53
        super();
×
54
        /*this.executorService = Executors.newCachedThreadPool(r -> {
55
            Thread t = Executors.defaultThreadFactory().newThread(r);
56
            t.setDaemon(true);
57
            return t;
58
        });
59
        this.timedSemaphore = null;
60
        this.futures = new HashMap<>();*/
61
        int nThreads = Runtime.getRuntime().availableProcessors();
×
62
        //int nThreads = (int) Math.ceil((double)Runtime.getRuntime().availableProcessors() / 2);
63
        LOGGER.debug("nThreads: " + nThreads);
×
64
        this.executorService = Executors.newFixedThreadPool(nThreads*2);
×
65
        //setLimits(20, 1000); // default calls per second
66
    }
×
67

68
    /*public void setLimits(int iterations, int interval) {
69
        if ((this.timedSemaphore == null)
70
            || (this.timedSemaphore.getLimit() != iterations)
71
            || (this.timedSemaphore.getPeriod() != interval)) {
72
            // custom executor to prevent stopping JVM from exiting
73
            this.timedSemaphore = new TimedSemaphore(new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
74
                @Override
75
                public Thread newThread(Runnable r) {
76
                    Thread t = Executors.defaultThreadFactory().newThread(r);
77
                    t.setDaemon(true);
78
                    return t;
79
                }
80
            }), interval, TimeUnit.MILLISECONDS, iterations);
81
        }
82
    }*/
83

84
    /*public synchronized void checkLimits() throws InterruptedException {
85
        if (this.limitAuto) {
86
            synchronized(this.timedSemaphore) {
87
                printLog(null, "timedSemaphore acquire... current total: " + this.timedSemaphore.getAcquireCount() + 
88
                    ", still available: " + this.timedSemaphore.getAvailablePermits() );
89
                this.timedSemaphore.acquire();
90
            }
91
        }
92
    }*/
93

94
    public static void printLog(GluttonRequest<?> request, String message) {
95
        LOGGER.debug((request != null ? request+": " : "")+message);
×
96
        //System.out.println((request != null ? request+": " : "")+message);
97
    }
×
98

99
    /**
100
     * Push a request in pool to be executed as soon as possible, then wait a response through the listener.
101
     */
102
    public <T extends Object> void pushRequest(GluttonRequest<T> request, CrossrefRequestListener<T> listener, 
103
        long threadId) throws URISyntaxException, ClientProtocolException, IOException {
104
        if (listener != null)
×
105
            request.addListener(listener);
×
106
        synchronized(this) {
×
107
            Future<?> f = executorService.submit(new GluttonRequestTask<T>(this, request));
×
108
            List<Future<?>> localFutures = this.futures.get(new Long(threadId));
×
109
            if (localFutures == null)
×
110
                localFutures = new ArrayList<Future<?>>();
×
111
            localFutures.add(f);
×
112
            this.futures.put(new Long(threadId), localFutures);
×
113
//System.out.println("add request to thread " + threadId + " / current total for the thread: " +  localFutures.size());         
114
        }
×
115
    }
×
116
    
117
    /**
118
     * Push a request in pool to be executed soon as possible, then wait a response through the listener.
119
     * 
120
     * @param params        query parameters, can be null, ex: ?query.title=[title]&query.author=[author]
121
     * @param deserializer  json response deserializer, ex: WorkDeserializer to convert Work to BiblioItem
122
     * @param threadId      the java identifier of the thread providing the request (e.g. via Thread.currentThread().getId())
123
     * @param listener      catch response from request
124
     */
125
    @Override
126
    public <T extends Object> void pushRequest(String model, Map<String, String> params, CrossrefDeserializer<T> deserializer, 
127
            long threadId, CrossrefRequestListener<T> listener) throws URISyntaxException, ClientProtocolException, IOException {
128
        GluttonRequest<T> request = new GluttonRequest<T>(model, params, deserializer);
×
129
        synchronized(this) {
×
130
            this.<T>pushRequest(request, listener, threadId);
×
131
        }
×
132
    }
×
133

134
    /**
135
     * Wait for all request from a specific thread to be completed
136
     */
137
    /*public void finish(long threadId) {
138
        synchronized(this.futures) {
139
            try {
140
                List<Future<?>> threadFutures = this.futures.get(new Long(threadId));
141
                if (threadFutures != null) {
142
//System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< thread: " + threadId + " / waiting for " + threadFutures.size() + " requests to finish...");
143
                    for(Future<?> future : threadFutures) {
144
                        future.get();
145
                        // get will block until the future is done
146
                    }
147
                    this.futures.remove(threadId);
148
                }
149
            } catch (InterruptedException ie) {
150
                // Preserve interrupt status
151
                Thread.currentThread().interrupt();
152
            } catch (ExecutionException ee) {
153
                logger.error("Glutton request execution fails");
154
            }
155
        }
156
    }*/
157

158
    /*@Override
159
    public void close() throws IOException {
160
        timedSemaphore.shutdown();
161
    }*/
162
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc