ActivityHandler.java 6.6 KB
package com.zhaoonline.coupen.handler;

import com.zhaoonline.coupen.bean.Activity;
import com.zhaoonline.coupen.bean.CommonCoupenEntity;
import com.zhaoonline.coupen.bean.CommonCoupenSeed;
import com.zhaoonline.coupen.bean.OwnerUser;
import com.zhaoonline.coupen.cache.RandomCache;
import com.zhaoonline.coupen.dispatcher.CoupenDispatchHandler;
import com.zhaoonline.coupen.dispatcher.UserCoupenMappingHandler;
import com.zhaoonline.coupen.lifecycle.LifeCycle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * Created by ZhaoOnline<br/>
 * User: yangyoupeng<br/>
 * Date: 2016/12/15<br/>
 * Time: 15:19<br/>
 * Description:活动处理器,该处理器的作用,是处理通过活动的入口进来领取红包。
 */
public class ActivityHandler {
    private Logger logger= LoggerFactory.getLogger(ActivityHandler.class);
    private CoupenDispatchHandler coupenDispatcher = null;
    private UserCoupenMappingHandler userCoupenMappingHandler= null;
    private LifeCycle lifeCycle = new LifeCycle();

    //保存有seed的缓存
    private RandomCache<String,CommonCoupenSeed> seedRandomCache=new RandomCache<String,CommonCoupenSeed>();

    private RandomCache<String,RandomCache<String,CommonCoupenEntity>> seedAndCoupenRandomCache=new RandomCache<String,RandomCache<String,CommonCoupenEntity>>();


    @Autowired
    public ActivityHandler(CoupenDispatchHandler coupenDispatcher,UserCoupenMappingHandler userCoupenMappingHandler){
        this.coupenDispatcher = coupenDispatcher;
        this.userCoupenMappingHandler =  userCoupenMappingHandler;
        lifeCycle.markStart();
    }

    /**
     * @param activity
     * @param user 点击活动入口的用户信息。领取红包,对于同一个用户。不可以重复获取
     * @return
     */
    public CommonCoupenEntity processRequest(Activity activity,OwnerUser user){
        warmCache(activity);
        CommonCoupenEntity mappedCoupenEntity = null;
        //首先会随机从获取一个seedID,然后获取seedID对应其中一个coupenEntity,如果仍然无法获得未分配的红包。那么就尝试去其他CounpenSeed。
        while(ObjectUtils.isEmpty(mappedCoupenEntity)) {
            if(seedRandomCache.isEmpty()){
                return null;
            }
            mappedCoupenEntity = tryDrawCoupen(seedRandomCache,seedAndCoupenRandomCache,user);
        }
        return mappedCoupenEntity;
    }

    private void warmCache(Activity activity) {
        //如果标记了,不需要进行缓存重置
        if(lifeCycle.checkNeedReload()){
            seedRandomCache.clear();
            seedAndCoupenRandomCache.clear();
        }

        if(seedRandomCache.isEmpty()){
            boolean coupenSeedWarmResult= warmCommonSeed(activity);
        }
        if(seedAndCoupenRandomCache.isEmpty()){
            boolean coupenEntityWarmResult=warmSeedAndCoupenRandmon(seedRandomCache,seedAndCoupenRandomCache);
        }

    }


    /**尝试获取一个红包
     * @param seedCache
     * @param seedAndCoupenCache
     * @param user
     * @return
     */
    private CommonCoupenEntity tryDrawCoupen(RandomCache<String,CommonCoupenSeed> seedCache, RandomCache<String,RandomCache<String,CommonCoupenEntity>> seedAndCoupenCache,OwnerUser user) {
        String randomSeedID=seedCache.randomKey();
        CommonCoupenSeed seed=seedCache.getCache(randomSeedID);

        if(ObjectUtils.isEmpty(seed)){
            return null;
        }

        RandomCache<String,CommonCoupenEntity> coupenCacheOfSeed= seedAndCoupenCache.getCache(seed.getSeedID());

        CommonCoupenEntity unmappedCoupenEntity=null;
        CommonCoupenEntity mappedCoupenEntity=null;
        while(ObjectUtils.isEmpty(mappedCoupenEntity)){
            unmappedCoupenEntity =randomGetCoupenFromCache(coupenCacheOfSeed);
            //如果最终cache里面的都coupenEntity都为空,那么则跳出循环。同时删除seedAndCoupenRandomCache中的CacheSeed
            if(ObjectUtils.isEmpty(unmappedCoupenEntity)){
                seedAndCoupenCache.remove(randomSeedID);
                break;
            }
            //若是该Coupen已经被领取了。直接删除缓存,然后直接返回
            if(!ObjectUtils.isEmpty(unmappedCoupenEntity.getOwnerUser())){
                coupenCacheOfSeed.remove(unmappedCoupenEntity.getCoupenID());
                break;
            }
            //这一步主要是将coupen和用户进行关系映射
            mappedCoupenEntity=userCoupenMappingHandler.mappingCoupen2User(unmappedCoupenEntity,user);
            //都需要将已经处理过的entity从缓存中删除
            coupenCacheOfSeed.remove(unmappedCoupenEntity.getCoupenID());
        }
        if(ObjectUtils.isEmpty(unmappedCoupenEntity)){
            seedCache.remove(randomSeedID);
        }
        return mappedCoupenEntity;
    }

    private boolean warmSeedAndCoupenRandmon(RandomCache<String, CommonCoupenSeed> seedRandomCache,RandomCache<String,RandomCache<String,CommonCoupenEntity>> cacheResult) {

        List<String> keys=seedRandomCache.allKeys();

        if(ObjectUtils.isEmpty(keys)){
            return false;
        }

        for(String seedID:keys){
            CommonCoupenSeed  seed=seedRandomCache.getCache(seedID);

            List<CommonCoupenEntity> allCoupenOfSeed= coupenDispatcher.dispacthCoupenEntityUsingSeed(seed);
            if(ObjectUtils.isEmpty(allCoupenOfSeed)){
                continue;
            }
            RandomCache<String,CommonCoupenEntity> coupenCache =new RandomCache<String,CommonCoupenEntity>();

            for(CommonCoupenEntity counpen:allCoupenOfSeed){
                coupenCache.put(counpen.getCoupenID(),counpen);
            }
            cacheResult.put(seed.getSeedID(),coupenCache);
        }
        return true;
    }


    private CommonCoupenEntity randomGetCoupenFromCache(RandomCache<String,CommonCoupenEntity> coupenCacheOfSeed){
        //随机获取一个红包ID
        String coupenEntityID=coupenCacheOfSeed.randomKey();
        CommonCoupenEntity coupenEntity=coupenCacheOfSeed.getCache(coupenEntityID);
        return coupenEntity;
    }

    private boolean warmCommonSeed(Activity activity) {
        List<CommonCoupenSeed> seedList = coupenDispatcher.dispatchCoupenSeedUsingActivity(activity);
        if (!ObjectUtils.isEmpty(seedList)){
            for (CommonCoupenSeed seed : seedList) {
                seedRandomCache.put(seed.getSeedID(), seed);
            }
            return true;
        }
        return false;
    }


    public LifeCycle getLifeCycle() {
        return lifeCycle;
    }
}