Static Data

There are two static data objects held in the RFQ sample (Instruments and Users). Instruments follows a pattern common for data that has a golden source outside the cluster.

The Instruments object holds the domain state for Instruments, and is very simple.

Adapter

The SbeAdapter is responsible for accepting data from the Aeron buffer data, and applying the changes to the Instruments repository. Supported methods include adding an instrument (AddInstrument), enabling/disabling and instrument (SetInstrumentEnabledFlag).

The route from raw buffer to adding an Instrument in the SbeAdapter is show below:

 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
public void dispatch(final DirectBuffer buffer, final int offset, final int length)
{
    if (length < MessageHeaderDecoder.ENCODED_LENGTH)
    {
        LOGGER.error("Message too short, ignored.");
        return;
    }
    headerDecoder.wrap(buffer, offset);

    switch (headerDecoder.templateId())
    {
        case AddInstrumentDecoder.TEMPLATE_ID -> addInstrument(buffer, offset);
        ...
    }
}

private void addInstrument(final DirectBuffer buffer, final int offset)
{
    addInstrumentDecoder.wrapAndApplyHeader(buffer, offset, headerDecoder);

    instruments.addInstrument(
        InstrumentAddType.INTERACTIVE,
        addInstrumentDecoder.correlation(),
        addInstrumentDecoder.cusip(),
        addInstrumentDecoder.enabled().equals(BooleanType.TRUE),
        addInstrumentDecoder.minSize());
}

Instruments

The Instruments object holds the Instrument static data at runtime, and provides key helper methods. This is plain old Java (though it does use an agrona hashmap).

 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
public class Instruments
{
    private static final int DEFAULT_MIN_VALUE = 0;
    private static final Logger LOGGER = LoggerFactory.getLogger(Instruments.class);
    private final ClusterClientResponder clusterClientResponder;

    private final Object2ObjectHashMap<String, Instrument> instrumentByCusip = new Object2ObjectHashMap<>();

    public Instruments(final ClusterClientResponder clusterClientResponder)
    {
        this.clusterClientResponder = clusterClientResponder;
    }

    public void addInstrument(
        final InstrumentAddType addType,
        final String correlation,
        final String cusip,
        final boolean enabled,
        final int minSize)
    {
        final Instrument instrument = new Instrument(cusip, enabled, minSize);
        instrumentByCusip.put(cusip, instrument);

        if (addType == InstrumentAddType.INTERACTIVE)
        {
            LOGGER.info("Added instrument {} to domain model", cusip);
            clusterClientResponder.sendInstrumentAdded(correlation);
        }
    }
    ...
}

Instrument

The instrument object itself is another plain old Java object:

public class Instrument
{
    private final String cusip;
    private final int minSize;
    private boolean enabled;

    public Instrument(final String cusip, final boolean enabled, final int minSize)
    {
        this.cusip = cusip;
        this.enabled = enabled;
        this.minSize = minSize;
    }

    public String getCusip()
    {
        return cusip;
    }

    public int getMinSize()
    {
        return minSize;
    }

    public boolean isEnabled()
    {
        return enabled;
    }

    public void setEnabled(final boolean enabled)
    {
        this.enabled = enabled;
    }

    @Override
    public boolean equals(final Object o)
    {
        if (this == o)
        {
            return true;
        }
        if (o == null || getClass() != o.getClass())
        {
            return false;
        }

        final Instrument that = (Instrument)o;

        return cusip.equals(that.cusip);
    }

    @Override
    public int hashCode()
    {
        return cusip.hashCode();
    }
}