API шлюза для блокирования вызовов API


Недавно у меня было интервью по программированию, где я должен создать API шлюза. Описание выглядит следующим образом:

Вам нужно создать шлюз, в котором он разрешает только определенное количество абонентов для вызова API и остальные будут заблокированы в течение определенного времени.

Например : если промежуток времени составляет 1 минуту. Вам нужно разрешить только 6 вызовов для вызова в том, что 1-минутное окно, а остальные будут заблокированы и будет разрешено только в следующем окне на 1 минуту.
Короче каждое окно позволит только 6 вызовов API.

Я не смог написать правильный код в течение 30 мин раунд, так как мой мозг начнет приливать ко всем видам решений.
Но я пытался сделать это однажды было сделано с интервью и ниже-это мое решение. Пожалуйста, дайте мне знать, если есть в любом случае, что я могу улучшить в реализации, с точки зрения производительности или каких-либо других аспектах.

public class APIGateway {
    private Employee emp;
    private int count = 0;
    private Timer timer;

    public APIGateway(Employee emp) {
        this.emp = emp;
        this.timer = new Timer(this);
        Thread t = new Thread(timer);
        t.start();
    }

    public synchronized void create() {
        while (!isAccessible()){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        emp.create();
        count++;
    }

    private synchronized boolean isAccessible() {
        if(count<6){
            return true;
        }
        return System.currentTimeMillis()<=timer.getElapsetime();
    }

    private synchronized void unblock(){
        count = 0;
        notifyAll();
    }

    private class Timer implements Runnable {
        private long startTime;
        private APIGateway gateway;

        Timer(APIGateway gateway){
            startTime = System.currentTimeMillis();
            this.gateway = gateway;
        }

        private long getElapsetime() {
            return startTime + 6000;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(60000);
                    startTime = System.currentTimeMillis();
                    gateway.unblock();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public void delete() {
        // same like create
    }

    public void update() {
        // same like create
    }
}

// Assume this is the api calls.
interface Employee {
    void create();
    void delete();
    void update();
}


136
3
задан 20 марта 2018 в 07:03 Источник Поделиться
Комментарии
1 ответ

Мое первое замечание было, что если я хочу регулирования для моих API, я бы поставил ее в какой-то перехватчик. Однако, так как это назначение интервью и для простоты я хотел воссоздать это как вызов функции:

public synchronized void create() {
if(isAccessible()) {
create(employer);
}
}

Во-вторых, я не думаю, что это хорошая идея, чтобы блок с циклом у вас, когда квота звонки были сделаны. Вместо того, чтобы вернуть осмысленное сообщение, которое объясняет, почему запрос был отклонен.

При текущей реализации вы используете выдачей InterruptedException в рамках вашего контроля потока, которое обычно считается анти-паттерн https://softwareengineering.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so-why.

Мне кажется более простым решением будет просто сбросить счетчик каждые 60 секунд в классе таймера, аналогично тому, что вы уже делаете. Может быть, я что-то упускаю, но я не понимаю, почему вы делаете проверку:

System.currentTimeMillis()<=timer.getElapsetime();

Вы уже сброс счетчика каждые 60 секунд, поэтому я бы просто возвращать false в этом методе.

Мое последнее замечание будет, что вообще был бы клиент передает работнику (или все необходимые данные для создания сотрудника) в запросе, так что не имеет смысла для работника в поле. Скорее это должен быть параметр создать функцию.

Если это интервью вопрос я хотел увидеть его как возможность поговорить о регулирования, и какие альтернативы есть. Например, может проверять стоимость звонков вместо фиксированного окна 60 секунд будет смысла. Однако это не то, что связанные с этим пересмотром кода.

2
ответ дан 21 марта 2018 в 05:03 Источник Поделиться