<commit_before>/*
 * Copyright (c) 2012-2014 Spotify AB
 *
 * 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.spotify.netty4.handler.codec.zmtp.benchmarks;

import com.spotify.netty4.handler.AutoFlusher;
import com.spotify.netty4.handler.codec.zmtp.ZMTP10Codec;
import com.spotify.netty4.handler.codec.zmtp.ZMTPMessageDecoder;
import com.spotify.netty4.handler.codec.zmtp.ZMTPMessageEncoder;
import com.spotify.netty4.handler.codec.zmtp.ZMTPSession;
import com.spotify.netty4.handler.codec.zmtp.ZMTPWriter;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.util.concurrent.Executor;

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.ImmediateEventExecutor;
import io.netty.util.internal.chmv8.ForkJoinPool;

import static com.spotify.netty4.handler.codec.zmtp.ZMTPConnectionType.Addressed;
import static com.spotify.netty4.handler.codec.zmtp.ZMTPSession.DEFAULT_SIZE_LIMIT;
import static com.spotify.netty4.handler.codec.zmtp.ZMTPSocketType.DEALER;
import static com.spotify.netty4.handler.codec.zmtp.ZMTPSocketType.ROUTER;
import static io.netty.util.CharsetUtil.UTF_8;

public class ApplicationBenchmark {

  private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);

  private static final byte[] NO_IDENTITY = null;

  private static final boolean INTEROP_ON = true;
  private static final boolean INTEROP_OFF = false;

  private static final InetSocketAddress ANY_PORT = new InetSocketAddress("127.0.0.1", 0);
  public static final Thread.UncaughtExceptionHandler
      UNCAUGHT_EXCEPTION_HANDLER =
      new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(final Thread thread, final Throwable throwable) {
          throwable.printStackTrace();
        }
      };

  public static void main(final String... args) throws InterruptedException {
    final ProgressMeter meter = new ProgressMeter("requests");

    // Codecs
    final ZMTP10Codec serverCodec = new ZMTP10Codec(
        new ZMTPSession(Addressed, DEFAULT_SIZE_LIMIT, NO_IDENTITY, ROUTER),
        new ReplyEncoder(),
        new RequestDecoder());

    final ZMTP10Codec clientCodec = new ZMTP10Codec(
        new ZMTPSession(Addressed, DEFAULT_SIZE_LIMIT, NO_IDENTITY, DEALER),
        new RequestEncoder(),
        new ReplyDecoder());

    // Server
    final Executor serverExecutor = new ForkJoinPool(
        1, ForkJoinPool.defaultForkJoinWorkerThreadFactory, UNCAUGHT_EXCEPTION_HANDLER, true);
    final ServerBootstrap serverBootstrap = new ServerBootstrap()
        .group(new NioEventLoopGroup(1), new NioEventLoopGroup())
        .channel(NioServerSocketChannel.class)
        .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
        .childHandler(new ChannelInitializer<NioSocketChannel>() {
          @Override
          protected void initChannel(final NioSocketChannel ch) throws Exception {
            ch.pipeline().addLast(serverCodec);
            ch.pipeline().addLast(ImmediateEventExecutor.INSTANCE, new AutoFlusher());
            ch.pipeline().addLast(new ServerHandler(serverExecutor));
          }
        });
    final Channel server = serverBootstrap.bind(ANY_PORT).awaitUninterruptibly().channel();

    // Client
    final Executor clientExecutor = new ForkJoinPool(
        1, ForkJoinPool.defaultForkJoinWorkerThreadFactory, UNCAUGHT_EXCEPTION_HANDLER, true);
    final SocketAddress address = server.localAddress();
    final Bootstrap clientBootstrap = new Bootstrap()
        .group(new NioEventLoopGroup())
        .channel(NioSocketChannel.class)
        .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
        .handler(new ChannelInitializer<NioSocketChannel>() {
          @Override
          protected void initChannel(final NioSocketChannel ch) throws Exception {
            ch.pipeline().addLast(clientCodec);
            ch.pipeline().addLast(ImmediateEventExecutor.INSTANCE, new AutoFlusher());
            ch.pipeline().addLast(new ClientHandler(meter, clientExecutor));
          }
        });
    final Channel client = clientBootstrap.connect(address).awaitUninterruptibly().channel();

    // Run until client is closed
    client.closeFuture().await();
  }

  private static class ServerHandler extends ChannelInboundHandlerAdapter {

    public static final ByteBuffer REPLY_PAYLOAD = UTF_8.encode("hello world");

    private final Executor executor;

    public ServerHandler(final Executor executor) {
      this.executor = executor;
    }

    @Override
    public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
      final Request request = (Request) msg;
      executor.execute(new Runnable() {
        @Override
        public void run() {
          ctx.write(request.reply(200, REPLY_PAYLOAD));
        }
      });
    }
  }

  private static class ClientHandler extends ChannelInboundHandlerAdapter {

    private static final int CONCURRENCY = 1000;

    private final ProgressMeter meter;
    private final Executor executor;

    public ClientHandler(final ProgressMeter meter, final Executor executor) {
      this.meter = meter;
      this.executor = executor;
    }

    @Override
    public void channelActive(final ChannelHandlerContext ctx) throws Exception {
      super.channelActive(ctx);
      for (int i = 0; i < CONCURRENCY; i++) {
        ctx.write(req());
      }
    }

    private Request req() {
      final long timestamp = System.nanoTime();
      return new Request("foo://bar/some/resource", "GET", timestamp, EMPTY_BUFFER);
    }

    @Override
    public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
      final Reply reply = (Reply) msg;
      final long latency = System.nanoTime() - reply.timestamp();
      meter.inc(1, latency);
      executor.execute(new Runnable() {
        @Override
        public void run() {
          ctx.write(req());
        }
      });
    }
  }

  private static class Message {

    private final CharSequence uri;
    private final CharSequence method;
    private final long timestamp;
    private final ByteBuffer payload;

    public Message(final CharSequence method, final CharSequence uri, final long timestamp,
                   final ByteBuffer payload) {
      this.method = method;<commit_msg>app benchmark: run all app logic on executor<commit_after>/*
 * Copyright (c) 2012-2014 Spotify AB
 *
 * 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.spotify.netty4.handler.codec.zmtp.benchmarks;

import com.spotify.netty4.handler.AutoFlusher;
import com.spotify.netty4.handler.codec.zmtp.ZMTP10Codec;
import com.spotify.netty4.handler.codec.zmtp.ZMTPMessageDecoder;
import com.spotify.netty4.handler.codec.zmtp.ZMTPMessageEncoder;
import com.spotify.netty4.handler.codec.zmtp.ZMTPSession;
import com.spotify.netty4.handler.codec.zmtp.ZMTPWriter;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.util.concurrent.Executor;

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.ImmediateEventExecutor;
import io.netty.util.internal.chmv8.ForkJoinPool;

import static com.spotify.netty4.handler.codec.zmtp.ZMTPConnectionType.Addressed;
import static com.spotify.netty4.handler.codec.zmtp.ZMTPSession.DEFAULT_SIZE_LIMIT;
import static com.spotify.netty4.handler.codec.zmtp.ZMTPSocketType.DEALER;
import static com.spotify.netty4.handler.codec.zmtp.ZMTPSocketType.ROUTER;
import static io.netty.util.CharsetUtil.UTF_8;

public class ApplicationBenchmark {

  private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);

  private static final byte[] NO_IDENTITY = null;

  private static final boolean INTEROP_ON = true;
  private static final boolean INTEROP_OFF = false;

  private static final InetSocketAddress ANY_PORT = new InetSocketAddress("127.0.0.1", 0);
  public static final Thread.UncaughtExceptionHandler
      UNCAUGHT_EXCEPTION_HANDLER =
      new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(final Thread thread, final Throwable throwable) {
          throwable.printStackTrace();
        }
      };

  public static void main(final String... args) throws InterruptedException {
    final ProgressMeter meter = new ProgressMeter("requests");

    // Codecs
    final ZMTP10Codec serverCodec = new ZMTP10Codec(
        new ZMTPSession(Addressed, DEFAULT_SIZE_LIMIT, NO_IDENTITY, ROUTER),
        new ReplyEncoder(),
        new RequestDecoder());

    final ZMTP10Codec clientCodec = new ZMTP10Codec(
        new ZMTPSession(Addressed, DEFAULT_SIZE_LIMIT, NO_IDENTITY, DEALER),
        new RequestEncoder(),
        new ReplyDecoder());

    // Server
    final Executor serverExecutor = new ForkJoinPool(
        1, ForkJoinPool.defaultForkJoinWorkerThreadFactory, UNCAUGHT_EXCEPTION_HANDLER, true);
    final ServerBootstrap serverBootstrap = new ServerBootstrap()
        .group(new NioEventLoopGroup(1), new NioEventLoopGroup())
        .channel(NioServerSocketChannel.class)
        .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
        .childHandler(new ChannelInitializer<NioSocketChannel>() {
          @Override
          protected void initChannel(final NioSocketChannel ch) throws Exception {
            ch.pipeline().addLast(serverCodec);
            ch.pipeline().addLast(ImmediateEventExecutor.INSTANCE, new AutoFlusher());
            ch.pipeline().addLast(new ServerHandler(serverExecutor));
          }
        });
    final Channel server = serverBootstrap.bind(ANY_PORT).awaitUninterruptibly().channel();

    // Client
    final Executor clientExecutor = new ForkJoinPool(
        1, ForkJoinPool.defaultForkJoinWorkerThreadFactory, UNCAUGHT_EXCEPTION_HANDLER, true);
    final SocketAddress address = server.localAddress();
    final Bootstrap clientBootstrap = new Bootstrap()
        .group(new NioEventLoopGroup())
        .channel(NioSocketChannel.class)
        .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
        .handler(new ChannelInitializer<NioSocketChannel>() {
          @Override
          protected void initChannel(final NioSocketChannel ch) throws Exception {
            ch.pipeline().addLast(clientCodec);
            ch.pipeline().addLast(ImmediateEventExecutor.INSTANCE, new AutoFlusher());
            ch.pipeline().addLast(new ClientHandler(meter, clientExecutor));
          }
        });
    final Channel client = clientBootstrap.connect(address).awaitUninterruptibly().channel();

    // Run until client is closed
    client.closeFuture().await();
  }

  private static class ServerHandler extends ChannelInboundHandlerAdapter {

    public static final ByteBuffer REPLY_PAYLOAD = UTF_8.encode("hello world");

    private final Executor executor;

    public ServerHandler(final Executor executor) {
      this.executor = executor;
    }

    @Override
    public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
      executor.execute(new Runnable() {
        @Override
        public void run() {
          final Request request = (Request) msg;
          ctx.write(request.reply(200, REPLY_PAYLOAD));
        }
      });
    }
  }

  private static class ClientHandler extends ChannelInboundHandlerAdapter {

    private static final int CONCURRENCY = 1000;

    private final ProgressMeter meter;
    private final Executor executor;

    public ClientHandler(final ProgressMeter meter, final Executor executor) {
      this.meter = meter;
      this.executor = executor;
    }

    @Override
    public void channelActive(final ChannelHandlerContext ctx) throws Exception {
      super.channelActive(ctx);
      for (int i = 0; i < CONCURRENCY; i++) {
        ctx.write(req());
      }
    }

    private Request req() {
      final long timestamp = System.nanoTime();
      return new Request("foo://bar/some/resource", "GET", timestamp, EMPTY_BUFFER);
    }

    @Override
    public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
      executor.execute(new Runnable() {
        @Override
        public void run() {
          final Reply reply = (Reply) msg;
          final long latency = System.nanoTime() - reply.timestamp();
          meter.inc(1, latency);
          ctx.write(req());
        }
      });
    }
  }

  private static class Message {

    private final CharSequence uri;
    private final CharSequence method;
    private final long timestamp;
    private final ByteBuffer payload;

    public Message(final CharSequence method, final CharSequence uri, final long timestamp,
                   final ByteBuffer payload) {
      this.method = method;
{'fraction_non_alphanumeric': 0.08751269035532995, 'fraction_numerical': 0.0075803722504230115, 'mean_word_length': 3.6465408805031445, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1797885', 'n_tokens_mistral': 4239, 'n_tokens_neox': 4138, 'n_words': 1024}