All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scouter.server.core.cache.ProfileDelayingCache Maven / Gradle / Ivy

There is a newer version: 2.20.0
Show newest version
package scouter.server.core.cache;
/*
 *  Copyright 2015 the original author or authors.
 *  @https://github.com/scouter-project/scouter
 *
 *  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.
 */

import scouter.lang.pack.XLogProfilePack2;
import scouter.server.Configure;
import scouter.server.Logger;
import scouter.server.core.ProfileDelayingsRecoverCore;
import scouter.util.LongKeyLinkedMap;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * Keep xlogs on memory for consequent xlog sampling.
 * all child xlogs follow commencement service's discarding option.
 * 

* Created by Gun Lee([email protected]) on 02/05/2020 */ public final class ProfileDelayingCache { public static ProfileDelayingCache instance = new ProfileDelayingCache(); private static final int BUCKET_MILLIS = 500; private Configure conf = Configure.getInstance(); private int lastMaxSize = 0; private long lastTime = System.currentTimeMillis() / BUCKET_MILLIS; private final ReferenceQueue>> referenceQueue; private LongKeyLinkedMap> gxidProfiles; private final LinkedList>>> gxidProfilesOld; private ProfileDelayingCache() { this.gxidProfiles = newMap(); this.gxidProfilesOld = new LinkedList<>(); this.referenceQueue = new ReferenceQueue<>(); try { ReferenceQueueHandler referenceQueueHandler = new ReferenceQueueHandler(referenceQueue); referenceQueueHandler.start(); } catch (Exception e) { Logger.printStackTrace(e); } } static class ReferenceQueueHandler extends Thread { private final ReferenceQueue>> referenceQueue; ReferenceQueueHandler(ReferenceQueue>> referenceQueue) { this.referenceQueue = referenceQueue; this.setName("SCOUTER-ProfileDelayingCache-ReferenceQueueHandler"); this.setDaemon(true); } @Override public void run() { try { while (true) { try { Reference>> reference = referenceQueue.remove(); Logger.println("S0101", "Consider heap increase, ProfileDelayingCache purged by GC, reference=" + reference); } catch (InterruptedException e) { Logger.println("S0102", "ProfileDelayingCache ReferenceQueueHandler interrupted!"); } } } catch (Throwable ex) { Logger.printStackTrace(ex); } } } public void addDelaying(XLogProfilePack2 profilePack) { if (profilePack.discardType == 0) { //in case of old version. (no discard type) return; } if (lastTime != System.currentTimeMillis() / BUCKET_MILLIS) { lastTime = System.currentTimeMillis() / BUCKET_MILLIS; lastMaxSize = Math.max(lastMaxSize, gxidProfiles.size()); int maxBucketCount = conf.xlog_sampling_matcher_profile_keep_memory_secs * 1000 / BUCKET_MILLIS; if (gxidProfilesOld.size() >= maxBucketCount) { for (int inx = gxidProfilesOld.size(); inx >= maxBucketCount; inx--) { SoftReference>> packsRef = gxidProfilesOld.removeFirst(); if (packsRef == null) { continue; } LongKeyLinkedMap> profilesInOld = packsRef.get(); if (profilesInOld == null) { continue; } ProfileDelayingsRecoverCore.add(profilesInOld); } } gxidProfilesOld.addLast(new SoftReference<>(gxidProfiles, referenceQueue)); gxidProfiles = newMap(); } List profilePacks = gxidProfiles.get(profilePack.gxid); if (profilePacks == null) { profilePacks = new ArrayList<>(); gxidProfiles.put(profilePack.gxid, profilePacks); } profilePacks.add(profilePack); } public void removeDelayingChildren(XLogProfilePack2 drivingPack) { if (drivingPack.isDriving()) { gxidProfiles.remove(drivingPack.txid); for (SoftReference>> profilesRef : gxidProfilesOld) { LongKeyLinkedMap> profilesInOld = profilesRef.get(); if (profilesInOld == null) { continue; } profilesInOld.remove(drivingPack.txid); } } } public List popDelayingChildren(XLogProfilePack2 drivingPack) { if (!drivingPack.isDriving()) { return Collections.emptyList(); } List children = gxidProfiles.get(drivingPack.txid); if (children != null) { gxidProfiles.remove(drivingPack.txid); } else { children = new ArrayList<>(); } for (SoftReference>> profilesRef : gxidProfilesOld) { LongKeyLinkedMap> profilesInOld = profilesRef.get(); if (profilesInOld == null) { continue; } List childrenInOld = profilesInOld.get(drivingPack.txid); if (childrenInOld != null) { profilesInOld.remove(drivingPack.txid); children.addAll(childrenInOld); } } return children; } private LongKeyLinkedMap> newMap() { int initSize = 0; if (lastMaxSize == 0) { initSize = 5 * 1000; } else { initSize = (int) (lastMaxSize * 1.5f); } LongKeyLinkedMap> map = new LongKeyLinkedMap<>(initSize, 0.75f); map.setMax(conf.xlog_sampling_matcher_profile_keep_memory_count); return map; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy