aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/test/java/com/yahoo/prelude/fastsearch/test/fs4mock/DispatchThread.java
blob: e5c0256a632ecd2f7912544332ec7c30e8473a7d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// -*- mode: java; folded-file: t; c-basic-offset: 4 -*-
//
//
package com.yahoo.prelude.fastsearch.test.fs4mock;


import com.yahoo.prelude.ConfigurationException;


/**
 * Thread-wrapper for MockFDispatch
 *
 * @author  <a href="mailto:borud@yahoo-inc.com">Bjorn Borud</a>
 */
public class DispatchThread extends Thread {
    int listenPort;
    long replyDelay;
    long byteDelay;
    MockFDispatch dispatch;
    Object barrier = new Object();

    /**
     * Instantiate MockFDispatch; if the wanted port is taken we
     * bump the port number.  Note that the delays are not
     * accurate: in reality they will be significantly longer for
     * low values.
     *
     * @param listenPort Wanted port number, note that this may be
     *                   bumped if someone is already running something
     *                   on this port, so it is a starting point for
     *                   scanning only
     * @param replyDelay how many milliseconds we should delay when
     *                   replying
     * @param byteDelay  how many milliseconds we delay for each byte
     *                   written
     */

    public DispatchThread(int listenPort, long replyDelay, long byteDelay) {
        this.listenPort = listenPort;
        this.replyDelay = replyDelay;
        this.byteDelay = byteDelay;
        dispatch = new MockFDispatch(listenPort, replyDelay, byteDelay);
        dispatch.setBarrier(barrier);
    }

    /**
     * Run the MockFDispatch and anticipate multiple instances of
     * same running.
     */
    public void run() {
        int maxTries = 20;
        // the following section is here to make sure that this
        // test is somewhat robust, ie. if someone is already
        // listening to the port in question, we'd like to NOT
        // fail, but keep probing until we find a port we can use.
        boolean up = false;

        while ((!up) && (maxTries-- != 0)) {
            try {
                dispatch.run();
                up = true;
            } catch (ConfigurationException e) {
                listenPort++;
                dispatch.setListenPort(listenPort);
            }
        }
    }

    /**
     * Wait until MockFDispatch is ready to accept connections
     * or we time out and indicate which of the two outcomes it was.
     *
     * @return If we time out we return <code>false</code>.  Else we
     *         return <code>true</code>
     *
     */
    public boolean waitOnBarrier(long timeout) throws InterruptedException {
        long start = System.currentTimeMillis();

        synchronized (barrier) {
            barrier.wait(timeout);
        }
        long diff = System.currentTimeMillis() - start;

        return (diff < timeout);
    }

    /**
     * Return the port on which the MockFDispatch actually listens.
     * use this instead of assuming where it is since, if more than
     * one application tries to use the port we've assigned to it
     * we might have to up the port number.
     *
     * @return port number of active MockFDispatch instance
     *
     */
    public int listenPort() {
        return listenPort;
    }
}