Github user anmolnar commented on a diff in the pull request:

    https://github.com/apache/zookeeper/pull/684#discussion_r230975652
  
    --- Diff: 
zookeeper-server/src/main/java/org/apache/zookeeper/server/ServerCnxn.java ---
    @@ -68,29 +70,74 @@
     
         private volatile boolean stale = false;
     
    +    final ZooKeeperServer zkServer;
    +
    +    public ServerCnxn(final ZooKeeperServer zkServer) {
    +        this.zkServer = zkServer;
    +    }
    +
         abstract int getSessionTimeout();
     
         abstract void close();
     
    +    public abstract void sendResponse(ReplyHeader h, Record r,
    +            String tag, String cacheKey, Stat stat) throws IOException;
    +
         public void sendResponse(ReplyHeader h, Record r, String tag) throws 
IOException {
    -        ByteArrayOutputStream baos = new ByteArrayOutputStream();
    -        // Make space for length
    +        sendResponse(h, r, tag, null, null);
    +    }
    +
    +    protected byte[] serializeRecord(Record record) throws IOException {
    +        ByteArrayOutputStream baos = new ByteArrayOutputStream(
    +            ZooKeeperServer.intBufferStartingSizeBytes);
             BinaryOutputArchive bos = BinaryOutputArchive.getArchive(baos);
    -        try {
    -            baos.write(fourBytes);
    -            bos.writeRecord(h, "header");
    -            if (r != null) {
    -                bos.writeRecord(r, tag);
    +        bos.writeRecord(record, null);
    +        return baos.toByteArray();
    +    }
    +
    +    protected ByteBuffer[] serialize(ReplyHeader h, Record r, String tag,
    +            String cacheKey, Stat stat) throws IOException {
    +        byte[] header = serializeRecord(h);
    +        byte[] data = null;
    +        if (r != null) {
    +            ResponseCache cache = zkServer.getReadResponseCache();
    +            if (cache != null && stat != null && cacheKey != null &&
    +                    !cacheKey.endsWith(Quotas.statNode)) {
    +                // Use cache to get serialized data.
    +                //
    +                // NB: Tag is ignored both during cache lookup and 
serialization,
    +                // since is is not used in read responses, which are being 
cached.
    +                data = cache.get(cacheKey, stat);
    +                if (data == null) {
    +                    // Cache miss, serialize the response and put it in 
cache.
    +                    data = serializeRecord(r);
    --- End diff --
    
    `put()` aquires the write lock anyway, so in my opinion this will cause the 
response to be serialized twice and put into the cache twice (second overwrites 
first). I think it's fine.


---

Reply via email to