Реализация наилучшей практики RestController в Spring Boot для отложенных сервисных ответов через wait () и notify () - PullRequest
0 голосов
/ 27 мая 2019

Мне удалось заставить код работать, и вызовы, кажется, работают так, как я намереваюсь. Однако мне интересно, реализую ли я здесь лучшие практики в отношении синхронизации объектов. Проблема заключается в том, что IB Api отправляет обратные вызовы методам, определенным в интерфейсе EWrapper, и при получении данных возникает задержка. Итак, я создал одноэлементный компонент, чтобы приостановить выполнение методов в контроллере транзакций, чтобы предотвратить чтение данных учетной записи до их обновления. Тем не менее, это выглядит несколько хакерской. Итак, мне интересно, в частности, каков наилучший подход для обработки подобных сценариев, и достаточно ли того, что я сделал.

    package com.vicentex.jdai.controllers;

    import javax.servlet.http.HttpServletRequest;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;

    import com.ib.client.Contract;
    import com.ib.client.Order;
    import com.vicentex.jdai.models.AccountSummary;
    import com.vicentex.jdai.models.ExecutionState;
    import com.vicentex.jdai.models.MarketOrderEntry;
    import com.vicentex.jdai.services.IBCommander;

    // TODO - Implement JWT Token Strategy
    @RestController
    public class TransactionController {

        @Autowired ExecutionState executionState;
        @Autowired IBCommander commander;


        @RequestMapping(value ="/createMarketOrder", method = RequestMethod.POST)
        public Contract testOrder(HttpServletRequest request, @RequestBody MarketOrderEntry payload) {

            Contract contract = this.commander.createStockContract(payload.getStock(), "STK", "USD", "SMART", "ISLAND");
            Order order = this.commander.createMarketOrder(payload.getQuantity(), payload.getDirection());
            this.commander.placeOrder(contract, order);

            return contract;
        }

        @RequestMapping(value ="/getTotalCashValue", method = RequestMethod.GET)
        public AccountSummary getTotalCashValue() throws InterruptedException {

            this.commander.getTotalCashValue();

            synchronized (this.executionState) {
                while (this.executionState.isRequestCompleted() == false) {
                    executionState.wait(100);
                }
                return this.commander.getAccountSummary();
            }

        }

        @RequestMapping(value ="/getSettledCash", method = RequestMethod.GET)
        public AccountSummary getSettledCash() throws InterruptedException {
            this.commander.getSettledCash();

            synchronized (this.executionState) {
                while (this.executionState.isRequestCompleted() == false) {
                    executionState.wait(100);
                }
                return this.commander.getAccountSummary();
            }

        }

        @RequestMapping(value ="/getBuyingPower", method = RequestMethod.GET)
        public AccountSummary getBuyingPower() throws InterruptedException {
            this.commander.getBuyingPower();

            synchronized (this.executionState) {
                while (this.executionState.isRequestCompleted() == false) {
                    executionState.wait(100);
                }
                return this.commander.getAccountSummary();
            }
        }

    }
...