diff --git a/Sources/Telegrammer/Dispatcher/Dispatcher.swift b/Sources/Telegrammer/Dispatcher/Dispatcher.swift index 5385f0b..8c045f4 100644 --- a/Sources/Telegrammer/Dispatcher/Dispatcher.swift +++ b/Sources/Telegrammer/Dispatcher/Dispatcher.swift @@ -16,11 +16,17 @@ import HTTP */ public class Dispatcher { + /// Telegram bot instance public let bot: Bot + + /// Queue in which passes all incoming updates public let updateQueue: DispatchQueue + + /// Worker which handle updates with appropriate handlers. Uses all available CPU cores by default. public let worker: Worker - public var handlersList: HandlersQueue + /// Queue which keep all added handlers and gives appropriates + public var handlersQueue: HandlersQueue public init(bot: Bot, worker: Worker = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)) { self.bot = bot @@ -30,9 +36,10 @@ public class Dispatcher { attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil) - self.handlersList = HandlersQueue() + self.handlersQueue = HandlersQueue() } + /// Enqueue new updates array to Updates queue public func enqueue(updates: [Update]) { updates.forEach { (update) in updateQueue.async { @@ -40,34 +47,36 @@ public class Dispatcher { } } } - - private func submit(update: Update) { - handlersList.handlers(for: update).forEach { (handler) in - _ = worker.eventLoop.submit { () -> Void in - try handler.handle(update: update, dispatcher: self) - } - } - } } public extension Dispatcher { - public func add(handler: T, to group: HandlerGroup = .zero) { - self.handlersList.add(handler, to: group) + func add(handler: T, to group: HandlerGroup = .zero) { + self.handlersQueue.add(handler, to: group) } - public func add(errorHandler: ErrorHandler) { - self.handlersList.add(errorHandler) + func add(errorHandler: ErrorHandler) { + self.handlersQueue.add(errorHandler) } - public func remove(handler: T, from group: HandlerGroup) { - self.handlersList.remove(handler, from: group) + func remove(handler: T, from group: HandlerGroup) { + self.handlersQueue.remove(handler, from: group) } - public func remove(errorHandler: ErrorHandler) { - self.handlersList.remove(errorHandler) + func remove(errorHandler: ErrorHandler) { + self.handlersQueue.remove(errorHandler) } } +private extension Dispatcher { + func submit(update: Update) { + handlersQueue.next(for: update).forEach { (handler) in + _ = worker.eventLoop.submit { () -> Void in + try handler.handle(update: update, dispatcher: self) + } + } + } +} + extension Dispatcher: HTTPServerResponder { public func respond(to request: HTTPRequest, on worker: Worker) -> Future { Log.info(""" diff --git a/Sources/Telegrammer/Dispatcher/HandlerGroup.swift b/Sources/Telegrammer/Dispatcher/HandlerGroup.swift index 9b6c592..fdf6fa9 100644 --- a/Sources/Telegrammer/Dispatcher/HandlerGroup.swift +++ b/Sources/Telegrammer/Dispatcher/HandlerGroup.swift @@ -7,6 +7,13 @@ import Foundation +/** Class of custom handlers group. + + `id` represent also priority of group, lower = higher priority. + Property `name` of group is used to determine when two group are equals. When you will try to remove + handler from `Dispatcher`, you will need to point, from which group to delete it by mention group `name`. + Also we offer predefined group called `zero`, which has highest priority and used in `Dispatcher` by default. + */ public class HandlerGroup: Hashable { public static func == (lhs: HandlerGroup, rhs: HandlerGroup) -> Bool { return lhs.id == rhs.id diff --git a/Sources/Telegrammer/Dispatcher/HandlersQueue.swift b/Sources/Telegrammer/Dispatcher/HandlersQueue.swift index ba63235..59cdc3b 100644 --- a/Sources/Telegrammer/Dispatcher/HandlersQueue.swift +++ b/Sources/Telegrammer/Dispatcher/HandlersQueue.swift @@ -74,7 +74,7 @@ public final class HandlersQueue { _handlersGroup = self._handlers.keys.sorted { $0.id < $1.id }.compactMap { _handlers[$0] } } - public func handlers(for update: Update) -> [Handler] { + public func next(for update: Update) -> [Handler] { var handlers: [Handler] = [] for group in _handlersGroup { concurrentQueue.sync { diff --git a/Sources/Telegrammer/Helpers/Constants.swift b/Sources/Telegrammer/Helpers/Constants.swift index 864c6aa..84c0eba 100644 --- a/Sources/Telegrammer/Helpers/Constants.swift +++ b/Sources/Telegrammer/Helpers/Constants.swift @@ -7,34 +7,17 @@ import Foundation -//telegram.constants.MAX_MESSAGE_LENGTH -//int – 4096 -// -//telegram.constants.MAX_CAPTION_LENGTH -//int – 200 -// -//telegram.constants.SUPPORTED_WEBHOOK_PORTS -//List[int] – [443, 80, 88, 8443] -// -//telegram.constants.MAX_FILESIZE_DOWNLOAD -//int – In bytes (20MB) -// -//telegram.constants.MAX_FILESIZE_UPLOAD -//int – In bytes (50MB) -// -//telegram.constants.MAX_MESSAGES_PER_SECOND_PER_CHAT -//int – 1. Telegram may allow short bursts that go over this limit, but eventually you’ll begin receiving 429 errors. -// -//telegram.constants.MAX_MESSAGES_PER_SECOND -//int – 30 -// -//telegram.constants.MAX_MESSAGES_PER_MINUTE_PER_GROUP -//int – 20 -// -//telegram.constants.MAX_INLINE_QUERY_RESULTS -//int – 50 -// -//The following constant have been found by experimentation: -// -//telegram.constants.MAX_MESSAGE_ENTITIES -//int – 100 (Beyond this cap telegram will simply ignore further formatting styles) +public struct Const { + static let MessageMaxLength: Int = 4096 + static let CaptionMaxLength: Int = 200 + static let WebhooksSupportedPorts: [Int] = [443, 80, 88, 8443] + static let DownloadFileMaxSize: Int = 20 //TODO: rewrite in bytes + static let UploadFileMaxSize: Int = 50 //TODO: rewrite in bytes + ///Telegram may allow short bursts that go over this limit, but eventually you’ll begin receiving 429 errors. + static let MessagesMaxPerSecondPerChat: Int = 1 + static let MessagesMaxPerSecond: Int = 30 + static let MessagesMaxPerMinutePerGroup: Int = 20 + static let InlineQueryMaxResults: Int = 50 + ///Beyond this cap telegram will simply ignore further formatting styles + static let MessagesMaxEntities: Int = 100 +}