degrade.js 4.99 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();

// memcached operation start
const memcachedGetter = (path) => new Promise(async (resolve, reject) => {
    let memcached = await getMemcached();

    memcached.get(path, (err, data) => {
        if (err) {
            console.log(`Got error when get "${path}" value from memcached`);
            resolve(false);
        } else {
            resolve(data === 'true');
        }

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

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

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

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

// 对某些path通过memcached处理值的存储
const gotoMemcached = path => path.indexOf('/pc/cart') > -1;

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) {

            // write memcached in modules of pc cart
            if (gotoMemcached(i.path)) {
                i.checked = await memcachedGetter(i.path);
            } else {
                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 result;

        if (gotoMemcached(path)) {
            result = await memcachedSetter(path, checked.toString());
        } else {
            let serverPath = await ctl.getServer();

            result = await setter(serverPath, path, checked.toString());
        }

        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;