Package org.apache.stratos.autoscaler

Source Code of org.apache.stratos.autoscaler.PartitionContext$PendingMemberWatcher

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.apache.stratos.autoscaler;

import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.stratos.autoscaler.util.ConfUtil;
import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition;
import org.apache.stratos.cloud.controller.stub.pojo.MemberContext;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;


/**
* This is an object that inserted to the rules engine.
* Holds information about a partition.
* @author nirmal
*
*/

public class PartitionContext implements Serializable{

  private static final long serialVersionUID = -2920388667345980487L;
  private static final Log log = LogFactory.getLog(PartitionContext.class);
    private String partitionId;
    private String serviceName;
    private String networkPartitionId;
    private Partition partition;
//    private int currentActiveMemberCount = 0;
    private int minimumMemberCount = 0;
    private int pendingMembersFailureCount = 0;
    private final int PENDING_MEMBER_FAILURE_THRESHOLD = 5;

    // properties
    private Properties properties;
   
    // 15 mints as the default
    private long expiryTime = 900000;
    // pending members
    private List<MemberContext> pendingMembers;

    // members to be terminated
    private List<String> obsoletedMembers;
   
    // Contains the members that CEP notified as faulty members.
//    private List<String> faultyMembers;
   
    // active members
    private List<MemberContext> activeMembers;

    // termination pending members, member is added to this when Autoscaler send grace fully shut down event
    private List<MemberContext> terminationPendingMembers;

    //Keep statistics come from CEP
    private Map<String, MemberStatsContext> memberStatsContexts;
    private int nonTerminatedMemberCount;
//    private int totalMemberCount;

    // for the use of tests
    public PartitionContext(long memberExpiryTime) {

        this.activeMembers = new ArrayList<MemberContext>();
        this.terminationPendingMembers = new ArrayList<MemberContext>();
        expiryTime = memberExpiryTime;
    }
   
    public PartitionContext(Partition partition) {
        this.setPartition(partition);
        this.minimumMemberCount = partition.getPartitionMin();
        this.partitionId = partition.getId();
        this.pendingMembers = new ArrayList<MemberContext>();
        this.activeMembers = new ArrayList<MemberContext>();
        this.terminationPendingMembers = new ArrayList<MemberContext>();
        this.obsoletedMembers = new CopyOnWriteArrayList<String>();
//        this.faultyMembers = new CopyOnWriteArrayList<String>();
        memberStatsContexts = new ConcurrentHashMap<String, MemberStatsContext>();

        // check if a different value has been set for expiryTime
        XMLConfiguration conf = ConfUtil.getInstance(null).getConfiguration();
        expiryTime = conf.getLong("autoscaler.member.expiryTimeout", 900000);
        if (log.isDebugEnabled()) {
            log.debug("Member expiry time is set to: " + expiryTime);
        }

        Thread th = new Thread(new PendingMemberWatcher(this));
        th.start();
    }
   
    public List<MemberContext> getPendingMembers() {
        return pendingMembers;
    }
   
    public void setPendingMembers(List<MemberContext> pendingMembers) {
        this.pendingMembers = pendingMembers;
    }
   
    public int getActiveMemberCount() {
        return activeMembers.size();
    }
   
    public void setActiveMembers(List<MemberContext> activeMembers) {
        this.activeMembers = activeMembers;
    }
   
    public String getPartitionId() {
        return partitionId;
    }
    public void setPartitionId(String partitionId) {
        this.partitionId = partitionId;
    }
//    public int getTotalMemberCount() {
//        // live count + pending count
//        return currentActiveMemberCount + pendingMembers.size();
//    }

//    public void incrementCurrentActiveMemberCount(int count) {
//
//        this.currentActiveMemberCount += count;
//    }
   
//    public void decrementCurrentActiveMemberCount(int count) {
//        this.currentActiveMemberCount -= count;
//    }

    public int getMinimumMemberCount() {
        return minimumMemberCount;
    }

    public void setMinimumMemberCount(int minimumMemberCount) {
        this.minimumMemberCount = minimumMemberCount;
    }

    public Partition getPartition() {
        return partition;
    }

    public void setPartition(Partition partition) {
        this.partition = partition;
    }
   
    public void addPendingMember(MemberContext ctxt) {
        this.pendingMembers.add(ctxt);
    }
   
    public boolean removePendingMember(String id) {
      if (id == null) {
            return false;
        }
        for (Iterator<MemberContext> iterator = pendingMembers.iterator(); iterator.hasNext();) {
        MemberContext pendingMember = (MemberContext) iterator.next();
        if(id.equals(pendingMember.getMemberId())){
          iterator.remove();
          return true;
        }
     
    }
     
      return false;
    }
   
    public void movePendingMemberToActiveMembers(String memberId) {
        if (memberId == null) {
            return;
        }
        Iterator<MemberContext> iterator = pendingMembers.listIterator();
        while (iterator.hasNext()) {
            MemberContext pendingMember = iterator.next();
            if(pendingMember == null) {
                iterator.remove();
                continue;
            }
            if(memberId.equals(pendingMember.getMemberId())){
                // member is activated
                // remove from pending list
                iterator.remove();
                // add to the activated list
                this.activeMembers.add(pendingMember);
                pendingMembersFailureCount = 0;
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Pending member is removed and added to the " +
                            "activated member list. [Member Id] %s",memberId));
                }
                break;
            }
        }
    }


    public void moveActiveMemberToTerminationPendingMembers(String memberId) {
        if (memberId == null) {
            return;
        }
        Iterator<MemberContext> iterator = activeMembers.listIterator();
        while ( iterator.hasNext()) {
            MemberContext activeMember = iterator.next();
            if(activeMember == null) {
                iterator.remove();
                continue;
            }
            if(memberId.equals(activeMember.getMemberId())){
                // member is activated
                // remove from pending list
                iterator.remove();
                // add to the activated list
                this.terminationPendingMembers.add(activeMember);
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Active member is removed and added to the " +
                            "termination pending member list. [Member Id] %s", memberId));
                }
                break;
            }
        }
    }
   
    public void addActiveMember(MemberContext ctxt) {
        this.activeMembers.add(ctxt);
    }
   
    public void removeActiveMember(MemberContext ctxt) {
        this.activeMembers.remove(ctxt);
    }

    public boolean removeTerminationPendingMember(String memberId) {
        boolean terminationPendingMemberAvailable = false;
        for (MemberContext memberContext: terminationPendingMembers){
            if(memberContext.getMemberId().equals(memberId)){
                terminationPendingMemberAvailable = true;
                terminationPendingMembers.remove(memberContext);
                break;
            }
        }
        return terminationPendingMemberAvailable;
    }
   
    public void addObsoleteMember(String memberId) {
        this.obsoletedMembers.add(memberId);
    }
   
    public boolean removeObsoleteMember(String memberId) {
        return this.obsoletedMembers.remove(memberId);
    }
//
//    public void addFaultyMember(String memberId) {
//        this.faultyMembers.add(memberId);
//    }
//
//    public boolean removeFaultyMember(String memberId) {
//        return this.faultyMembers.remove(memberId);
//    }
//
//    public List<String> getFaultyMembers() {
//        return this.faultyMembers;
//    }

    public long getExpiryTime() {
        return expiryTime;
    }

    public void setExpiryTime(long expiryTime) {
        this.expiryTime = expiryTime;
    }
   
    public List<String> getObsoletedMembers() {
        return obsoletedMembers;
    }
       
    public void setObsoletedMembers(List<String> obsoletedMembers) {
        this.obsoletedMembers = obsoletedMembers;
    }

    public String getNetworkPartitionId() {
        return networkPartitionId;
    }

    public void setNetworkPartitionId(String networkPartitionId) {
        this.networkPartitionId = networkPartitionId;
    }

   
    public Map<String, MemberStatsContext> getMemberStatsContexts() {
        return memberStatsContexts;
    }

    public MemberStatsContext getMemberStatsContext(String memberId) {
        return memberStatsContexts.get(memberId);
    }

    public void addMemberStatsContext(MemberStatsContext ctxt) {
        this.memberStatsContexts.put(ctxt.getMemberId(), ctxt);
    }

    public void removeMemberStatsContext(String memberId) {
        this.memberStatsContexts.remove(memberId);
    }

    public MemberStatsContext getPartitionCtxt(String id) {
        return this.memberStatsContexts.get(id);
    }

//    public boolean memberExist(String memberId) {
//        return memberStatsContexts.containsKey(memberId);
//    }


    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public String getServiceName() {
        return serviceName;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }

    public List<MemberContext> getTerminationPendingMembers() {
        return terminationPendingMembers;
    }

    public void setTerminationPendingMembers(List<MemberContext> terminationPendingMembers) {
        this.terminationPendingMembers = terminationPendingMembers;
    }

    public int getTotalMemberCount() {

        return activeMembers.size() + pendingMembers.size() + terminationPendingMembers.size();
    }

    public int getNonTerminatedMemberCount() {
        return activeMembers.size() + pendingMembers.size() + terminationPendingMembers.size();
    }

    public boolean removeActiveMemberById(String memberId) {
        boolean removeActiveMember = false;
        synchronized (activeMembers) {
            Iterator<MemberContext> iterator = activeMembers.listIterator();
            while (iterator.hasNext()) {
                MemberContext memberContext = iterator.next();
                if(memberId.equals(memberContext.getMemberId())){
                    iterator.remove();
                    removeActiveMember = true;

                    break;
                }
            }
        }
        return removeActiveMember;
    }

    public boolean activeMemberExist(String memberId) {

        for (MemberContext memberContext: activeMembers) {
            if(memberId.equals(memberContext.getMemberId())){
                return true;
            }
        }
        return false;
    }

    private class PendingMemberWatcher implements Runnable {
        private PartitionContext ctxt;

        public PendingMemberWatcher(PartitionContext ctxt) {
            this.ctxt = ctxt;
        }

        @Override
        public void run() {

            while (true) {
                long expiryTime = ctxt.getExpiryTime();
                List<MemberContext> pendingMembers = ctxt.getPendingMembers();
               
                synchronized (pendingMembers) {
                    Iterator<MemberContext> iterator = pendingMembers.listIterator();
                    while ( iterator.hasNext()) {
                        MemberContext pendingMember = iterator.next();

                        if (pendingMember == null) {
                            continue;
                        }
                        long pendingTime = System.currentTimeMillis() - pendingMember.getInitTime();
                        if (pendingTime >= expiryTime) {


                            iterator.remove();
                            log.info("Pending state of member: " + pendingMember.getMemberId() +
                                     " is expired. " + "Adding as an obsoleted member.");
                            // member should be terminated
                            ctxt.addObsoleteMember(pendingMember.getMemberId());
                            pendingMembersFailureCount++;
                            if( pendingMembersFailureCount > PENDING_MEMBER_FAILURE_THRESHOLD){
                                setExpiryTime(expiryTime * 2);//Doubles the expiry time after the threshold of failure exceeded
                                //TODO Implement an alerting system: STRATOS-369
                            }
                        }
                    }
                }

                try {
                    // TODO find a constant
                    Thread.sleep(15000);
                } catch (InterruptedException ignore) {
                }
            }
        }

    }
}
TOP

Related Classes of org.apache.stratos.autoscaler.PartitionContext$PendingMemberWatcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.