bkdnOJv2 / bkdnOJ-v2

A new Online Judge system for Danang University of Science and Technology to replace the previous old DOMjudge-based system. More responsive, more modern, more flexible. (To be updated)
https://bkdnoj.com
0 stars 0 forks source link

[BUG] Bridge trong Production đôi khi freeze, không gửi submission cho judge servers nữa #37

Closed nvatuan closed 1 year ago

nvatuan commented 2 years ago

Hiện tượng trên đến hôm nay (16/08/2022) đã xảy ra 2 lần, lý do vẫn chưa rõ. Cần nghiên cứu vì sao lại có hiện tượng này.

Sẽ cập nhập thêm

nvatuan commented 2 years ago

Có vẻ như hiện tượng này xảy ra là do chúng ta không cẩn thận đóng connection mỗi khi sử lý submission tại bridge. Một nguyên nhân có thể là Dmoj Dev đã vô tình "buộc" solution của họ với MySQL, khiến các DB khác không chạy đoạn code này:

    def _update_ping(self):
        try:
            Judge.objects.filter(name=self.name).update(ping=self.latency, load=self.load)
        except Exception as e:
            # What can I do? I don't want to tie this to MySQL.
            if e.__class__.__name__ == 'OperationalError' and e.__module__ == '_mysql_exceptions' and e.args[0] == 2006:
                db.connection.close()

Đoạn code trên có thể không liên quan, nhưng dùng để nhắc cho ta biết hiện tượng (db-specific solution) là có thật

nvatuan commented 2 years ago

Solution tạm thời mà tôi suggest là clear idle connections mỗi một khoảng thời gian. Nhưng mà mỗi khoảng thời gian thì phải deploy thêm một task scheduler hoặc viết script cronjob gì nữa, (introduce một thành phần mới vào hệ thống) nên tôi không muốn. Bây giờ cứ mỗi (vd là 500) 500 submissions, nó sẽ clear idle connection. Fix như sau:

if submission.id % SUBMISSIONS_COUNT_TO_CLEAR_IDLE == 0:
    logger.info('>> Reached %d subs, clearing idle connections...', SUBMISSIONS_COUNT_TO_CLEAR_IDLE)
    db.close_old_connections()
    with db.connection.cursor() as cursor:
        sql = "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle'"
        cursor.execute(sql)
        row = cursor.fetchall()
        logger.info('>> Cleared %d idle connections.', len(row))

Và rất là ironic, cái này cũng là db-specific solution.

nvatuan commented 2 years ago

Solution tạm thời đã được deploy, issue chuyển sang on-hold chờ đợi thông tin thêm.

nvatuan commented 2 years ago

Hiện tượng này vẫn diễn ra... Chắc chịu quá hic

nvatuan commented 2 years ago

Bắt đầu re-investigate vấn đề này.

nvatuan commented 1 year ago

This issue no longer occurs during and after ICPC Central Province 2022 strangely enough. Either the patching works, or raising the max memory limit on each uwsgi worker resolves this. If the latter was the solution, I guess when worker was killed because of mem limit violation it didn't close the DB connection properly leading to DB connection leaking.