From 58d91666649ad5e90969c3eff7d7926346e42143 Mon Sep 17 00:00:00 2001 From: Shun Fan Date: Thu, 21 Apr 2016 15:17:27 -0700 Subject: [PATCH] Update memcache sample with code from docs pages --- .../memcache/MemcacheAsyncCacheServlet.java | 75 ++++++++++++++++ ....java => MemcacheBestPracticeServlet.java} | 2 +- .../memcache/MemcacheConcurrentServlet.java | 85 +++++++++++++++++++ .../memcache/MemcacheSyncCacheServlet.java | 67 +++++++++++++++ .../src/main/webapp/WEB-INF/appengine-web.xml | 2 +- .../memcache/src/main/webapp/WEB-INF/web.xml | 32 ++++++- 6 files changed, 257 insertions(+), 6 deletions(-) create mode 100644 appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheAsyncCacheServlet.java rename appengine/memcache/src/main/java/com/example/appengine/memcache/{MemcacheServlet.java => MemcacheBestPracticeServlet.java} (96%) create mode 100644 appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheConcurrentServlet.java create mode 100644 appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheSyncCacheServlet.java diff --git a/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheAsyncCacheServlet.java b/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheAsyncCacheServlet.java new file mode 100644 index 00000000000..802777e8481 --- /dev/null +++ b/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheAsyncCacheServlet.java @@ -0,0 +1,75 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.appengine.memcache; + +import com.google.appengine.api.memcache.AsyncMemcacheService; +import com.google.appengine.api.memcache.ErrorHandlers; +import com.google.appengine.api.memcache.MemcacheServiceFactory; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.logging.Level; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@SuppressWarnings("serial") +public class MemcacheAsyncCacheServlet extends HttpServlet { + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, + ServletException { + String path = req.getRequestURI(); + if (path.startsWith("/favicon.ico")) { + return; // ignore the request for favicon.ico + } + + // [START example] + AsyncMemcacheService asyncCache = MemcacheServiceFactory.getAsyncMemcacheService(); + asyncCache.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO)); + String key = "count-async"; + byte[] value; + long count = 1; + Future futureValue = asyncCache.get(key); // Read from cache. + // ... Do other work in parallel to cache retrieval. + try { + value = (byte[]) futureValue.get(); + if (value == null) { + value = BigInteger.valueOf(count).toByteArray(); + asyncCache.put(key, value); + } else { + // Increment value + count = new BigInteger(value).longValue(); + count++; + value = BigInteger.valueOf(count).toByteArray(); + // Put back in cache + asyncCache.put(key, value); + } + } catch (InterruptedException | ExecutionException e) { + throw new ServletException("Error when waiting for future value", e); + } + // [END example] + + // Output content + resp.setContentType("text/plain"); + resp.getWriter().print("Value is " + count + "\n"); + } +} diff --git a/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheServlet.java b/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheBestPracticeServlet.java similarity index 96% rename from appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheServlet.java rename to appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheBestPracticeServlet.java index 1f18110ae8b..8283fc16532 100644 --- a/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheServlet.java +++ b/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheBestPracticeServlet.java @@ -30,7 +30,7 @@ // [START example] @SuppressWarnings("serial") -public class MemcacheServlet extends HttpServlet { +public class MemcacheBestPracticeServlet extends HttpServlet { @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, diff --git a/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheConcurrentServlet.java b/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheConcurrentServlet.java new file mode 100644 index 00000000000..8d3280e23d3 --- /dev/null +++ b/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheConcurrentServlet.java @@ -0,0 +1,85 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.appengine.memcache; + +import com.google.appengine.api.memcache.MemcacheService; +import com.google.appengine.api.memcache.MemcacheService.IdentifiableValue; +import com.google.appengine.api.memcache.MemcacheServiceFactory; + +import java.io.IOException; +import java.math.BigInteger; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +// [START example] +@SuppressWarnings("serial") +public class MemcacheConcurrentServlet extends HttpServlet { + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, + ServletException { + String path = req.getRequestURI(); + if (path.startsWith("/favicon.ico")) { + return; // ignore the request for favicon.ico + } + + String key = "count-concurrent"; + // Using the synchronous cache. + MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService(); + + // Write this value to cache using getIdentifiable and putIfUntouched. + for (long delayMs = 1; delayMs < 1000; delayMs *= 2) { + IdentifiableValue oldValue = syncCache.getIdentifiable(key); + byte[] newValue = oldValue == null + ? BigInteger.valueOf(0).toByteArray() + : increment((byte[]) oldValue.getValue()); // newValue depends on old value + resp.setContentType("text/plain"); + resp.getWriter().print("Value is " + new BigInteger(newValue).intValue() + "\n"); + if (oldValue == null) { + // Key doesn't exist. We can safely put it in cache. + syncCache.put(key, newValue); + break; + } else if (syncCache.putIfUntouched(key, oldValue, newValue)) { + // newValue has been successfully put into cache. + break; + } else { + // Some other client changed the value since oldValue was retrieved. + // Wait a while before trying again, waiting longer on successive loops. + try { + Thread.sleep(delayMs); + } catch (InterruptedException e) { + throw new ServletException("Error when sleeping", e); + } + } + } + } + + /** + * Increments an integer stored as a byte array by one. + * @param oldValue a byte array with the old value + * @return a byte array as the old value increased by one + */ + private byte[] increment(byte[] oldValue) { + long val = new BigInteger(oldValue).intValue(); + val++; + return BigInteger.valueOf(val).toByteArray(); + } +} +// [END example] diff --git a/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheSyncCacheServlet.java b/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheSyncCacheServlet.java new file mode 100644 index 00000000000..b517256bf18 --- /dev/null +++ b/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheSyncCacheServlet.java @@ -0,0 +1,67 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.appengine.memcache; + +import com.google.appengine.api.memcache.ErrorHandlers; +import com.google.appengine.api.memcache.MemcacheService; +import com.google.appengine.api.memcache.MemcacheServiceFactory; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.logging.Level; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +// [START example] +@SuppressWarnings("serial") +public class MemcacheSyncCacheServlet extends HttpServlet { + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, + ServletException { + String path = req.getRequestURI(); + if (path.startsWith("/favicon.ico")) { + return; // ignore the request for favicon.ico + } + + MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService(); + syncCache.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO)); + String key = "count-sync"; + byte[] value; + long count = 1; + value = (byte[]) syncCache.get(key); + if (value == null) { + value = BigInteger.valueOf(count).toByteArray(); + syncCache.put(key, value); + } else { + // Increment value + count = new BigInteger(value).longValue(); + count++; + value = BigInteger.valueOf(count).toByteArray(); + // Put back in cache + syncCache.put(key, value); + } + + // Output content + resp.setContentType("text/plain"); + resp.getWriter().print("Value is " + count + "\n"); + } +} +// [END example] diff --git a/appengine/memcache/src/main/webapp/WEB-INF/appengine-web.xml b/appengine/memcache/src/main/webapp/WEB-INF/appengine-web.xml index ad825e10799..089c609c550 100644 --- a/appengine/memcache/src/main/webapp/WEB-INF/appengine-web.xml +++ b/appengine/memcache/src/main/webapp/WEB-INF/appengine-web.xml @@ -1,7 +1,7 @@