BaseX parrallel Client

45 Views Asked by At

I have client like this :

import org.basex.api.client.ClientSession;

@Slf4j
@Component(value = "baseXAircrewClient")
@DependsOn(value = "baseXAircrewServer")
public class BaseXAircrewClient {

    @Value("${basex.server.host}")
    private String basexServerHost;

    @Value("${basex.server.port}")
    private int basexServerPort;

    @Value("${basex.admin.password}")
    private String basexAdminPassword;
    

    @Getter
    private ClientSession session;

    @PostConstruct
    private void createClient() throws IOException {
        log.info("##### Creating BaseX client session {}", basexServerPort);
        this.session = new ClientSession(basexServerHost, basexServerPort, UserText.ADMIN, basexAdminPassword);
        
    }
}

It is a singleton injected in a service which run mulitple queries like this :

Query query = client.getSession().query(finalQuery);
            return query.execute();

All threads query and share the same session. With a single thread all is fine but with multiple thread I get some random (and weird) error, like the result of a query to as a result of another.

I feel that I should put a synchronized(){} arround query.execute() or open and close session for each query, or create a pool of session. But I don't find any documentation how the use the session in parrallel. Is this implementation fine for multithreading (and my issue is comming from something else) or should I do it differently ?

1

There are 1 best solutions below

0
jpprade On

I ended creating a simple pool by adding removing the client from a ArrayBlockingQueue and it is working nicely :

@PostConstruct
private void createClient() throws IOException {
    log.info("##### Creating BaseX client session {}", basexServerPort);
    final int poolSize = 5;

    this.resources = new ArrayBlockingQueue < ClientSession > (poolSize) {
        {
            for (int i = 0; i < poolSize; i++) {
                add(initClient());
            }
        }
    };
}

private ClientSession initClient() throws IOException {
    ClientSession clientSession = new ClientSession(basexServerHost, basexServerPort, UserText.ADMIN, basexAdminPassword);
    return clientSession;
}

public Query query(String finalQuery) throws IOException {
    ClientSession clientSession = null;
    try {
        clientSession = resources.take();

        Query result = clientSession.query(finalQuery);

        return result;
    } catch (InterruptedException e) {
        log.error("Error during query execution: " + e.getMessage(), e);
    } finally {
        if (clientSession != null) {
            try {
                resources.put(clientSession);
            } catch (InterruptedException e) {
                log.error("Error adding to pool : " + e.getMessage(), e);
            }
        }
    }

    return null;
}