A simple, asynchronous, single-threaded memcached client written in java.
Java Other
#33 Compare This branch is 1 commit ahead of dustin:master.
amcrn and Matt Ingenthron Fix ConcurrentModificationException for getStats Op
If the result of MemcachedClient.getStats() is immediately iterated
over, a ConcurrentModificationException can be thrown if the
operationTimeout value has been exceeded before mutations to the
Map have completed.

Example:

* blatch.await(operationTimeout, TimeUnit.MILLISECONDS); returns
  false after waiting `operationTimeout`, resulting in
  MemcachedClient.getStats() returning the `rv` Map.
* While the caller starts to iterate over the Map, the
  StatsOperation.Callback's gotStat mutates the Map, resulting in
  a ConcurrentModificationException.

How to Reproduce:

```
public static void main(String[] args) throws Exception {
  ConnectionFactory connectionFactory = new ConnectionFactoryBuilder()
    .setProtocol(Protocol.TEXT)
    .setFailureMode(FailureMode.Cancel)
    .setOpTimeout(1)
    .build();
  MemcachedClient client = new MemcachedClient(
    connectionFactory, AddrUtil.getAddresses("localhost:11211"));
  while(true) {
    Map<SocketAddress, Map<String, String>> allStats = client.getStats();
    if (allStats.isEmpty()) continue;
    Map<String, String> stats = allStats.entrySet().iterator().next().getValue();
    for(Entry<String,String> stat : stats.entrySet()) {
      System.out.println(stat.getKey() + " => " + stat.getValue());
    }
  }
}
```

Output:

```
2017-11-02 14:37:52.269 WARN net.spy.memcached.MemcachedClient:  Unsuccessful stat fetch: {OperationStatus success=false:  timed out}
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:922)
	at java.util.HashMap$EntryIterator.next(HashMap.java:962)
	at java.util.HashMap$EntryIterator.next(HashMap.java:960)
	at com.xxx.xxx.xxx.xxx.xxx.StatsBug.main(StatsBug.java:31)
  ```

Notes:

* Written in a way to be completely backwards compatible.
* Guarantees that the caller only sees the entire stats result for a
  SocketAddress, or no result at all. Converting the Maps to
  ConcurrentHashMaps alone would result in partially complete
  Maps.

Change-Id: If51e074a13f809581c8bad119b393edb2c4d4788
Reviewed-on: http://review.couchbase.org/91953
Reviewed-by: Matt Ingenthron <ingenthr@gmail.com>
Tested-by: Matt Ingenthron <ingenthr@gmail.com>
Latest commit eb5d6ee Nov 2, 2017

README.markdown

Building

Spymemcached can be compiled using Apache Ant by running the following command:

ant

This will generate binary, source, and javadoc jars in the build directory of the project.

To run the Spymemcached tests against Membase Server run the following command:

ant test -Dserver.type=membase

To test Spymemcached against Membase running on a different host use the following command:

ant test -Dserver.type=membase \
    -Dserver.address_v4=ip_address_of_membase

Testing

The latest version of spymemcached has a set of command line arguments that can be used to configure the location of your testing server. The arguments are listed below.

-Dserver.address_v4=ipv4_address_of_testing_server

This argument is used to specify the ipv4 address of your testing server. By default it is set to localhost.

-Dserver.address_v6=ipv6_address_of_testing_server

This argument is used to set the ipv6 address of your testing server. By default it is set to ::1. If an ipv6 address is specified then an ipv4 address must be specified otherwise there may be test failures.

-Dserver.port_number=port_number_of_memcached

This argument is used when memcahched is started on a port other than 11211

-Dtest.type=ci

This argument is used for CI testing where certain unit tests might be temporarily failing.

More Information

For more information about Spymemcached see the links below:

Project Page The

Spymemcached Project Home contains a wiki, issue tracker, and downloads section.

Github

The gitub page contains the latest Spymemcached source.

Couchbase.org

At couchbase.org you can find a download's section for the latest release as well as an extensive tutorial to help new users learn how to use Spymemcached.