The TCP Lateral Auxiliary Cache is an optional plug in for the JCS. It is primarily intended to broadcast puts and removals to other local caches, though it can also get cached objects. It functions by opening up a SocketServer that listens to a configurable port and by creating Socket connections with other local cache SocketServers. It can be configured to connect to any number of servers.
If there is an error connecting to another server or if an error occurs in transmission, it will move into a recovery mode. In recovery mode the TCP Lateral Auxiliary Cache will continue to communicate with healthy servers while it tries to restore the connection with the server that is in error.
The cache hub communicates with a facade that implements a zombie pattern (balking facade) to prevent blocking. Puts and removals are queued and occur synchronously in the background. Get requests are synchronous and can potentially block for a configurable interval if there is a communication problem.
The configuration is fairly straightforward and is done in the auxiliary cache section of the cache.ccf configuration file. In the example below, I created a TCP Lateral Auxiliary Cache referenced by LTCP. It connects to two servers defined in a comma separated list in the TcpServers attribute. It listens to port 1110 and does AllowGet. Setting AllowGet equal to false would cause the auxiliary cache to return null from any get request. In most cases this attribute should be set to false, since if the lateral caches were properly configured, the elements in one would be present in all.
jcs.auxiliary.LTCP=org.apache.commons.jcs.auxiliary.lateral.socket.tcp.LateralTCPCacheFactory jcs.auxiliary.LTCP.attributes=org.apache.commons.jcs.auxiliary.lateral.socket.tcp.TCPLateralCacheAttributes jcs.auxiliary.LTCP.attributes.TcpServers=localhost:1111,localhost:1112 jcs.auxiliary.LTCP.attributes.TcpListenerPort=1110 jcs.auxiliary.LTCP.attributes.AllowGet=true
A mostly configurationless mode is available for the TCP lateral cache if you use the UDP Discovery mechanism.
You can configure the TCP lateral cache to operate in send only mode by setting the Receive attribute to false. By default the receive attribute is true. When it is set to false, the lateral cache will not establish a socket server.
Setting receive to false allows you to broadcast puts and removes, but not receive any. This is useful for nodes of an application that produce data, but are not involved in data retrieval.
The configuration below is the same as above, except the Receive attribute is set to false. It also uses UDP discovery to find the servers, rather than listing them in the servers attribute.
jcs.auxiliary.LTCP=org.apache.commons.jcs.auxiliary.lateral.socket.tcp.LateralTCPCacheFactory jcs.auxiliary.LTCP.attributes=org.apache.commons.jcs.auxiliary.lateral.socket.tcp.TCPLateralCacheAttributes #jcs.auxiliary.LTCP.attributes.TcpServers= jcs.auxiliary.LTCP.attributes.TcpListenerPort=1118 jcs.auxiliary.LTCP.attributes.UdpDiscoveryAddr=126.96.36.199 jcs.auxiliary.LTCP.attributes.UdpDiscoveryPort=6780 jcs.auxiliary.LTCP.attributes.UdpDiscoveryEnabled=true jcs.auxiliary.LTCP.attributes.Receive=true jcs.auxiliary.LTCP.attributes.AllowGet=false jcs.auxiliary.LTCP.attributes.IssueRemoveOnPut=false jcs.auxiliary.LTCP.attributes.FilterRemoveByHashCode=false
The TCP Lateral Auxiliary Cache can provide a high level of consistency but it does not guarantee consistency between caches. A put for the same object could be issued in two different local caches. Since the transmission is queued, a situation could occur where the item put last in one cache is overridden by a put request from another local cache. The two local caches could potentially have different versions of the same item. Like most caches, this is intended for high get and low put utilization, and this occurrence would hint at improper usage. The RMI Remote cache makes this situation a bit less likely to occur, since the default behavior is to remove local copies on put operations. If either local cache needed the item put in the above situation, it would have to go remote to retrieve it. Both local copies would have been expired and would end up using the same version, though it is possible that the version stored remotely would not be the last version created. The OCS4J tries to implement a locking system to prevent this from occurring, but the locking system itself could suffer from similar problems (when granting locks from two roughly simultaneous lock requests) and it would create a significant burden on all the caches involved. Since this situation would be extremely rare and is nearly impossible to solve practically, for now JCS will not offer any type of locking.