-
Notifications
You must be signed in to change notification settings - Fork 16
Description
Cheers to everyone at Clojurewerkz! Developing a web app with Monger and Spyglass was an absolute joy, and I'm glad you're out there abstracting ConnectionFactoryBuilders for people like me.
I'm still running into an SASL error connecting a Heroku app to a remote Memcached server. The client still seems to be using the ASCII protocol, even when I use clojurewerkz.spyglass.client/bin-connection. I saw that there was an authentication fix in the latest beta, so I grabbed the new code and replaced bin-connection and all its dependencies in my project, but it throws the same exception: java.lang.UnsupportedOperationException: SASL is not supported for ASCII protocol.
I solved this issue by using the example in this blog post to set up my client and pass it to spyglass, but I'm not a Java dev and have no idea what I'm doing when I have to deal with interop stuff.
Here's my code:
(ns partial-applications.memcachehacks
(:import [net.spy.memcached.auth AuthDescriptor PlainCallbackHandler]
net.spy.memcached.transcoders.Transcoder
net.spy.memcached.transcoders.SerializingTranscoder
[net.spy.memcached MemcachedClient
ConnectionFactory
BinaryConnectionFactory
ConnectionFactoryBuilder
ConnectionFactoryBuilder$Protocol
FailureMode
AddrUtil]
[java.io ByteArrayOutputStream ByteArrayInputStream File]
[java.net InetSocketAddress]))
(defn- servers
[^String server-list]
(AddrUtil/getAddresses server-list))
(defprotocol AsFailureMode
(^FailureMode to-failure-mode [input]))
(extend-protocol AsFailureMode
FailureMode
(to-failure-mode [input]
input)
String
(to-failure-mode [input]
(case input
"redistribute" FailureMode/Redistribute
"retry" FailureMode/Retry
"cancel" FailureMode/Cancel))
clojure.lang.Named
(to-failure-mode [input]
(to-failure-mode (name input))))
(defn- ^ConnectionFactory customize-factory
[^ConnectionFactory cf {:keys [failure-mode transcoder auth-descriptor]}]
(let [;; Houston, we have a *FactoryFactory here!
cfb (ConnectionFactoryBuilder. cf)]
(when failure-mode
(.setFailureMode cfb (to-failure-mode failure-mode)))
(when transcoder
(.setTranscoder cfb transcoder))
(when auth-descriptor
(.setAuthDescriptor cfb auth-descriptor))
(.build cfb)))
(defn ^ConnectionFactory bin-connection-factory
[& {:as opts}]
(customize-factory (BinaryConnectionFactory.) opts))
(defn bin-connection
"Returns a new binary protocol client that will use the provided list of servers."
([^String server-list]
(MemcachedClient. (BinaryConnectionFactory.) (servers server-list)))
([^String server-list ^BinaryConnectionFactory cf]
(MemcachedClient. cf (servers server-list)))
([^String server-list ^String username ^String password]
(let [ad (AuthDescriptor/typical username password)]
(MemcachedClient. (bin-connection-factory :auth-descriptor ad) (servers server-list)))))
(defn connect [server user pw]
(let [auth (AuthDescriptor/typical user pw)
tmc-client (bin-connection server
(bin-connection-factory
:failure-mode :redistribute
:auth-descriptor auth))]
tmc-client))
And here's the whole error (server address redacted):
2013-02-15 21:35:13.297 INFO net.spy.memcached.MemcachedConnection: Added {QA sa=MEMCACHE_SERVER:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2013-02-15 21:35:13.373 INFO net.spy.memcached.MemcachedConnection: Connection state changed for sun.nio.ch.SelectionKeyImpl@5777b4d3
Exception in thread "Thread-5" java.lang.UnsupportedOperationException: SASL is not supported for ASCII protocol
at net.spy.memcached.protocol.ascii.AsciiOperationFactory.saslAuth(AsciiOperationFactory.java:172)
at net.spy.memcached.auth.AuthThread.buildOperation(AuthThread.java:117)
at net.spy.memcached.auth.AuthThread.run(AuthThread.java:86)
2013-02-15 21:35:13.457:INFO:oejs.Server:jetty-7.6.1.v20120215
Started server on port 3000
2013-02-15 21:35:13.497:INFO:oejs.AbstractConnector:Started [email protected]:3000
Exception: net.spy.memcached.OperationTimeoutException: Timeout waiting for value
MemcachedClient.java:1009 net.spy.memcached.MemcachedClient.get
MemcachedClient.java:1024 net.spy.memcached.MemcachedClient.get
client.clj:105 clojurewerkz.spyglass.client/get
database.clj:20 partial-applications.database/cached-get
handler.clj:22 partial-applications.handler/get-strategy
handler.clj:37 partial-applications.handler/main-handler
response.clj:27 compojure.response/eval1073[fn]
response.clj:10 compojure.response/eval1034[fn]
core.clj:93 compojure.core/make-route[fn]
core.clj:39 compojure.core/if-route[fn]
core.clj:24 compojure.core/if-method[fn]
core.clj:106 compojure.core/routing[fn]
core.clj:2390 clojure.core/some
core.clj:106 compojure.core/routing
RestFn.java:139 clojure.lang.RestFn.applyTo
core.clj:603 clojure.core/apply
core.clj:111 compojure.core/routes[fn]
keyword_params.clj:27 ring.middleware.keyword-params/wrap-keyword-params[fn]
nested_params.clj:65 ring.middleware.nested-params/wrap-nested-params[fn]
params.clj:55 ring.middleware.params/wrap-params[fn]
multipart_params.clj:103 ring.middleware.multipart-params/wrap-multipart-params[fn]
flash.clj:14 ring.middleware.flash/wrap-flash[fn]
session.clj:43 ring.middleware.session/wrap-session[fn]
cookies.clj:160 ring.middleware.cookies/wrap-cookies[fn]
Var.java:415 clojure.lang.Var.invoke
reload.clj:18 ring.middleware.reload/wrap-reload[fn]
stacktrace.clj:15 ring.middleware.stacktrace/wrap-stacktrace-log[fn]
stacktrace.clj:79 ring.middleware.stacktrace/wrap-stacktrace-web[fn]
jetty.clj:18 ring.adapter.jetty/proxy-handler[fn]
(Unknown Source) ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$0.handle
HandlerWrapper.java:111 org.eclipse.jetty.server.handler.HandlerWrapper.handle
Server.java:349 org.eclipse.jetty.server.Server.handle
AbstractHttpConnection.java:452 org.eclipse.jetty.server.AbstractHttpConnection.handleRequest
AbstractHttpConnection.java:884 org.eclipse.jetty.server.AbstractHttpConnection.headerComplete
AbstractHttpConnection.java:938 org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete
HttpParser.java:634 org.eclipse.jetty.http.HttpParser.parseNext
HttpParser.java:230 org.eclipse.jetty.http.HttpParser.parseAvailable
AsyncHttpConnection.java:76 org.eclipse.jetty.server.AsyncHttpConnection.handle
SelectChannelEndPoint.java:609 org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle
SelectChannelEndPoint.java:45 org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run
QueuedThreadPool.java:599 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob
QueuedThreadPool.java:534 org.eclipse.jetty.util.thread.QueuedThreadPool$3.run
Thread.java:680 java.lang.Thread.run
Caused by: net.spy.memcached.internal.CheckedOperationTimeoutException: Timed out waiting for operation - failing node: MEMCACHE_SERVER:11211
OperationFuture.java:159 net.spy.memcached.internal.OperationFuture.get
GetFuture.java:62 net.spy.memcached.internal.GetFuture.get
MemcachedClient.java:1003 net.spy.memcached.MemcachedClient.get