degrade.js 4.51 KB
'use strict';

import Router from 'koa-router';
import moment from 'moment';
import _ from 'lodash';
import process from 'process';

import {Degrade, DegradeServer, MemcachedHost} from '../../models';

import getter from '../../zookeeper/getter';
import setter from '../../zookeeper/setter';
import tester from '../../zookeeper/tester';

import Memcached from 'memcached';

const router = new Router();

const memcachedSetter = async (path, value) => {
    let memcached = await getMemcached();

    memcached.set(path, value, 2592000, (err) => {
        if (err) {
            console.log(`set ${path} memcached value error`);
        } else {
            console.log(`set ${path} memcached value to: ${value} success`);
        }

        process.nextTick(() => {
            memcached.end();
        });
    });
};

// 对某些path通过memcached处理值的存储
// /pc/cart , /pc/common
const gotoMemcached = path => /^\/pc\/(common|cart)\//.test(path);

const getMemcached = async () => {
    let queryHosts = await MemcachedHost.findAll();
    let hosts;

    if (queryHosts.length === 0) {
        hosts = ['memcache1.yohoops.org:12111', 'memcache2.yohoops.org:12111', 'memcache3.yohoops.org:12111'];
    } else {
        hosts = _.map(queryHosts, 'host');
    }

    return new Memcached(hosts);
}
// memcached operation end

const ctl = {
    async getServer() {
        let server = await DegradeServer.findAll({});

        server = _.last(server);

        if (server) {
            return `${server.ip}:${server.port}`;
        }
    },
    async index (ctx) {
        let serverPath = await ctl.getServer();
        let serverSplit = serverPath ? serverPath.split(':') : ['', ''];

        await ctx.render('action/degrade', {
            ip: serverSplit[0],
            port: serverSplit[1]
        });
    },
    async connect(ctx) {
        let {ip, port} = ctx.query;

        let server = `${ip}:${port}`;

        let connected = await tester(server);

        // connecting test
        if (!connected) {
            ctx.body = `<p class="connect-err">
                <i class="fa fa-wheelchair" aria-hidden="true"></i>
                Sorry, I can not connect to <span class="server-name">${server}</span>.Please check whether your ip/port is correct or the zookeeper server is running
                </p>`;
            return;
        }

        let degrades = await Degrade.findAll();

        for(let i of degrades) {
            // 从zookeeper读取配置信息,memcached只做PHP读取使用
            i.checked = await getter(server, i.path);
        }

        let pc = _.filter(degrades, o => _.startsWith(o.path, '/pc'));
        let wap = _.filter(degrades, o => _.startsWith(o.path, '/wap'));

        await ctx.render('action/degrade_list', {
            layout: false,
            pc: pc,
            wap: wap
        });
    },
    async server(ctx) {
        let ip = ctx.request.body.ip;
        let port = ctx.request.body.port;

        let serverCount = await DegradeServer.count({});

        // keep one server 
        if (serverCount) {
            let serverConfig = await DegradeServer.findAll({});
            let id = _.last(serverConfig)._id; // get the latest item

            await DegradeServer.update({
                _id: id
            }, {
                $set: {
                    ip: ip,
                    port: port
                }
            });
        } else {
            await DegradeServer.insert({
                ip: ip,
                port: port
            });
        }

        ctx.body = {
            code: 200,
            message: `${serverCount ? 'update' : 'new'} server success`
        };
    },
    async setter(ctx) {
        let {checked, id} = ctx.query;

        let theDegrade = await Degrade.findById(id);

        let path = theDegrade.path;

        let serverPath = await ctl.getServer();
        let result = await setter(serverPath, path, checked.toString());

        // 如果要设置memcached,再次写memcached
        if (gotoMemcached(path)) {
            memcachedSetter(path, checked.toString());
        }

        // result结果以zookeeper写为准
        if (result) {
            ctx.body = {
                code: 200,
                message: 'update success'
            };
        } else {
            ctx.body = {
                code: 500,
                message: 'update fail,Please retry'
            }
        }
    }
};

router.get('/', ctl.index);
router.post('/server', ctl.server);
router.get('/connect', ctl.connect);
router.get('/setter', ctl.setter);

export default router;