java.net.SocketException: операция не разрешена (выбор / опрос не выполнен) при асинхронном добавлении событий Keen в AWS Lambda - PullRequest
0 голосов
/ 27 июня 2018

Зависимость:

<dependency>
    io.keen</groupId>
    keen-client-api-java</artifactId>
    5.2.0</
</dependency>

Создание бина:

@Bean
public KeenClient keenClient() {
    KeenClient keenClient = new JavaKeenClientBuilder().build();
    keenClient.setDefaultProject(new KeenProject(projectId, writeKey, readKey));
    keenClient.setDebugMode(debugMode);

    if (enableLogging) {
        KeenLogging.enableLogging();
    }

    return keenClient;
}

Определение услуги:

@Service
public class KeenAnalyticsService implements AnalyticsService {
    private static final Logger LOG = LoggerFactory.getLogger(KeenAnalyticsService.class);

    private final KeenClient keenClient;

    public static final String ID = "id";
    public static final String USER_LOGIN_EVENT = "user_login_event";

    @Autowired
    public KeenAnalyticsService(KeenClient keenClient) {
        this.keenClient = keenClient;
    }

    @Override
    public void submitUserLoginEvent(UserLoginAnalyticsEvent userLoginAnalyticsEvent) {
        Map<String, Object> event = Maps.newHashMap();
        event.put(USER_LOGIN_EVENT, userLoginAnalyticsEvent);
        addEvent(USER_LOGIN_EVENT, event);
    }

    private void addEvent(String collection, Map<String, Object> event) {
        addEvent(collection, event, Maps.newHashMap());
    }

    private void addEvent(String collection, Map<String, Object> event, Map<String, Object> keenProperties) {
        if (!event.containsKey(ID)) {
            String id = UUID.randomUUID().toString();
            LOG.info("Adding {} Keen event with ID ({})", collection, id);
            event.put(ID, id);
        } else {
            LOG.info("Adding {} Keen event with existing ID ({})", collection, event.get(ID));
        }

            try {
            keenClient.addEventAsync(keenClient.getDefaultProject(), collection, event, keenProperties, new LoggingKeenCallback());
        } catch (Throwable e) {
            LOG.warn("Unable to add event", e);
        }
    }

    private static class LoggingKeenCallback implements KeenDetailedCallback {
        @Override
        public void onSuccess() {}

        @Override
        public void onFailure(Exception e) {}

        @Override
        public void onSuccess(KeenProject project, String eventCollection, Map<String, Object> event, Map<String, Object>     keenProperties) {
            LOG.info("Successfully processed event asynchronously with ID({}) to Collection({})", event.get(ID),     eventCollection);
        }

        @Override
        public void onFailure(KeenProject project, String eventCollection, Map<String, Object> event, Map<String, Object>     keenProperties, Exception e) {
            LOG.warn("Unable to process event asynchronously with ID({}) to Collection({})", event.get(ID), eventCollection,     e);
        }
    }

}

Я получаю следующую трассировку стека:

Exception in thread "pool-1-thread-1" java.lang.RuntimeException: java.net.SocketException: Operation not permitted (select/    poll failed)
    at io.keen.client.java.KeenClient.handleFailure(KeenClient.java:1643)
    at io.keen.client.java.KeenClient.addEvent(KeenClient.java:171)
    at io.keen.client.java.KeenClient$1.run(KeenClient.java:243)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketException: Operation not permitted (select/poll failed)
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
    at sun.security.ssl.InputRecord.read(InputRecord.java:503)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1316)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1291)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
    at io.keen.client.java.http.UrlConnectionHttpHandler.sendRequest(UrlConnectionHttpHandler.java:86)
    at io.keen.client.java.http.UrlConnectionHttpHandler.execute(UrlConnectionHttpHandler.java:30)
    at io.keen.client.java.KeenClient.publishObject(KeenClient.java:1436)
    at io.keen.client.java.KeenClient.publish(KeenClient.java:1370)
    at io.keen.client.java.KeenClient.addEvent(KeenClient.java:168)
    ... 4 more

Есть какие-нибудь идеи относительно того, что может быть причиной проблемы? Эта проблема исчезает, когда я добавляю событие в синхронизации, а не в асинхронном режиме, но я бы предпочел добавить событие асинхронным, если это возможно.

Я на 99% уверен, что это лямбда, отсекающая выполнение до середины события, но я хотел быть уверен. Я лично не распознаю стековую трассировку, поэтому я могу только предположить, что из этого получилось.

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

Опять же, лямбда может быть достаточно умна, чтобы дождаться окончания порожденных детьми потоков. С другой стороны, это не может быть. Может завершиться, когда основной поток завершит работу по проекту.

Интересно, может ли кто-нибудь из команды Keen или команды Lambda пролить на это больше света?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...