/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved. <a>http://www.crunii.com</a>
 */
package com.crunii.micro.platform.log.impl;

import com.crunii.micro.common.queue.ObjectEvent;
import com.crunii.micro.common.queue.impl.AbstractFastQueueHandler;
import com.crunii.micro.common.utils.StopUtil;
import com.crunii.micro.domain.entitysql.main.TSqlLogS;
import com.crunii.micro.platform.service.SqlLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import java.util.concurrent.*;

/**
 * @author 田平 create 2019年5月15日下午4:44:39
 */
@Slf4j
@Component
public class SqlLogFastQueueHandler extends AbstractFastQueueHandler<TSqlLogS> {

	@Autowired
	private SqlLogService sqlLogService;

	private static ExecutorService executor = new ThreadPoolExecutor(4, 8, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(),
			new RejectedExecutionHandler() {
				@Override
				public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
					if (!executor.isShutdown()) {
						try {
							executor.getQueue().put(r);
						} catch (InterruptedException e) {
							log.warn("executor Interrupted", e);
						}
					}
				}
			});

	@PreDestroy
	public void destroy() {
		StopUtil.stopES(executor);
	}

	@Override
	public void handler(ObjectEvent<TSqlLogS> event, long sequence, boolean endOfBatch) {
		TSqlLogS sqlLog = event.getVal();
		if (sqlLog == null) {
			log.info("TSqlLog is null");
			return;
		}
		sendAsync(sqlLog);
		//释放资源,必须释放否则可能引起内存溢出
		event.clear();
	}

	private void sendAsync(TSqlLogS sqlLog) {
		executor.execute(() -> {
			try {
				sqlLogService.createTSqlLog(sqlLog);
			} catch (Exception e) {
				log.error("Direct insert database error!{}", sqlLog, e);
			}
		});
	}

}
