several fixes and krontab migration

This commit is contained in:
InsanusMokrassar 2023-06-10 13:39:41 +06:00
parent fe91bd17a6
commit 089d0cebac
14 changed files with 311 additions and 17 deletions

View File

@ -0,0 +1,58 @@
# KrontabScheduler
`KronScheduler` is the simple interface with only one function `next`. This function optionally get as a parameter `DateTime` which will be used as start point for the calculation of next trigger time. This function will return the next `DateTime` when something must happen.
### Default realisation
Default realisation (`CronDateTimeScheduler`) can be created using several ways:
* Via `buildSchedule` (or `createSimpleScheduler`) functions with crontab-like syntax parameter
* Via `buildSchedule` (or `SchedulerBuilder` object), which using lambda to configure scheduler
In the examples below the result of created scheduler will be the same.
#### Crontab-like way
> NOTE: **Crontab-like syntax**
> See [String format](string-format.md) for more info about the crontab-line syntax
This way will be very useful for cases when you need to configure something via external configuration (from file on startup or via some parameter from requests, for example):
```kotlin
val schedule = "5 * * * *"
val scheduler = buildSchedule(schedule)
scheduler.asFlow().onEach {
// this block will be called every minute at 5 seconds
}.launchIn(someCoroutineScope)
```
#### Lambda way
In case of usage builder (lets call it `lambda way`), you will be able to configure scheduler in more type-safe way:
```kotlin
val scheduler = buildSchedule {
seconds {
at(5)
}
}
scheduler.asFlow().onEach {
// this block will be called every minute at 5 seconds
}.launchIn(someCoroutineScope)
```
### Custom scheduler
You are always able to use your own realisation of scheduler. For example:
```kotlin
class RandomScheduler : KronScheduler {
override suspend fun next(relatively: DateTime): DateTime {
return relatively + DateTimeSpan(seconds = Random.nextInt() % 60)
}
}
```
In the example above we have created `RandomScheduler`, which will return random next time in range `0-60` seconds since `relatively` argument.

View File

@ -0,0 +1,117 @@
# String format
As in `crontab` util, this library have almost the same format of string:
| | Seconds | Minutes | Hours | Days of months | Months | Years | Timezone Offset | Week days | Milliseconds |
| --: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| Range | 0..59 | 0..59 | 0..23 | 0..30 | 0..11 | Any `Int` | Any `Int` | 0..6 | 0..999 |
| Suffix | - | - | - | - | - | - | `o` | `w` | `ms` |
| Optional | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| [Full syntax](#bkmrk-supported-syntax) support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| Position | 0 | 1 | 2 | 3 | 4 | Any after months | Any after months | Any after months | Any after months |
| Examples | `0`, `*/15`, `30` | `0`, `*/15`, `30` | `0`, `*/15`, `22` | `0`, `*/15`, `30` | `0`, `*/5`, `11` | `0`, `*/15`, `30` | `60o` (UTC+1) | `0w`, `*/2w`, `4w` | `0ms`, `*/150ms`, `300ms` |
Example with almost same description:
```
/-------------------- (0-59) ············ Seconds
| /------------------ (0-59) ············ Minutes
| | /---------------- (0-23) ············ Hours
| | | /-------------- (0-30) ············ Days of months
| | | | /------------ (0-11) ············ Months
| | | | | /---------- (optional, any int) Year
| | | | | | /-------- (optional) ········ Timezone offset
| | | | | | | /----- (optional, 0-6) ··· Week days
| | | | | | | | /-- (optional, 0-999) · Milliseconds (0 by default)
* * * * * * 0o *w 0ms
```
Years, timezone, week days and milliseconds are optional settings. Next snippets are equal:
```
*/15 * * * *
*/15 * * * * * // with year
*/15 * * * * * 0ms // with year and milliseconds
```
### Supported syntax
Currently the library support next syntax for date/time elements:
* `{int}-{int}` - ranges
* `{int}/{int}` - start/step
* `*/{int}` - every {int}
* `{int}` - just at the time
* `{other_element},{other_element}` - listing
* `F` or `f` - first possible value
* `L` or `l` - last possible value (last day of month, for example)
#### Ranges
Ranges are working like common `rangeTo` (or `..`) in kotlin:
```
0-5 * * * *
```
In the example above scheduler will trigger every second from the beginning of the minute up to fifth second of minute.
#### Start/Step
Start/step is a little bit more complicated syntax. It means `start from the first element, repeat triggering every second element`. Examples:
```
5/15 * * * *
```
Means that each minute starting from fifth second it will repeat triggering every fifteenth second: `5, 20, 35, 50`.
#### Every
Every is more simple syntax and could be explained as a shortcut for `0/{int}`. Example:
```
*/15 * * * *
```
Means that each minute it will repeat triggering every fifteenth second: `0, 15, 30, 45`.
#### Just at the time
The most simple syntax. It means, that scheduler will call triggering every time when element was reached:
```
15 * * * *
```
Means that each minute scheduler will call triggering at the fifteenth second.
#### Listing
All the previous elements can be combined with listing. Lets just see several examples:
```
0,10 * * * *
```
Will trigger every minute at the `0` and `10` seconds (see [Just at the time](#just-at-the-time))
```
0-5,10 * * * *
```
Will trigger every minute from `0` to `5` seconds and at the `10` seconds (see [Ranges](#ranges))
### Examples
* `0/5 * * * *` for every five seconds triggering
* `0/5,L * * * *` for every five seconds triggering and on 59 second
* `0/15 30 * * *` for every 15th seconds in a half of each hour
* `0/15 30 * * * 500ms` for every 15th seconds in a half of each hour when milliseconds equal to 500
* `1 2 3 F,4,L 5` for triggering in near first second of second minute of third hour of first, fifth and last days of may
* `1 2 3 F,4,L 5 60o` for triggering in near first second of second minute of third hour of first, fifth and last days of may with timezone UTC+01:00
* `1 2 3 F,4,L 5 60o 0-2w` for triggering in near first second of second minute of third hour of first, fifth and last days of may in case if it will be in Sunday-Tuesday week days with timezone UTC+01:00
* `1 2 3 F,4,L 5 2021` for triggering in near first second of second minute of third hour of first, fifth and last days of may of 2021st year
* `1 2 3 F,4,L 5 2021 60o` for triggering in near first second of second minute of third hour of first, fifth and last days of may of 2021st year with timezone UTC+01:00
* `1 2 3 F,4,L 5 2021 60o 0-2w` for triggering in near first second of second minute of third hour of first, fifth and last days of may of 2021st year if it will be in Sunday-Tuesday week days with timezone UTC+01:00
* `1 2 3 F,4,L 5 2021 60o 0-2w 500ms` for triggering in near first second of second minute of third hour of first, fifth and last days of may of 2021st year if it will be in Sunday-Tuesday week days with timezone UTC+01:00 when milliseconds will be equal to 500

View File

@ -0,0 +1,19 @@
# FAQ
#### How oftern new versions are releasing?
Not very often. It depend on libraries (coroutines, korlibs/klock) updates and on some new awesome, but lightweight, features coming.
#### Where this library could be useful?
First of all, this library will be useful for long uptime applications which have some tasks to do from time to time.
#### How to use crontab-like syntax?
In two words, you should call `buildSchedule` or `createSimpleScheduler`:
```kotlin
buildSchedule("5 * * * *").asFlow().collect { /* do something */ }
```
You can read more about syntax in [String format](../describing/string-format.md) section.

View File

@ -0,0 +1,57 @@
# How to use
## Previous pages
* [Including in project](including-in-project.md)
## `buildSchedule`
> NOTE: **Custom KronScheduler**
> You always able to create your own scheduler. In this section will be presented different ways and examples around standard `CronDateTimeScheduler` builders `buildSchedule`. You can read about schedulers in [KrontabScheduler](../describing/krontabscheduler.md)
Currently, `buildSchedule` is the recommended start point for every scheduler. Usually, it is look like:
```kotlin
val scheduler = buildSchedule("5 * * * *")
```
Or:
```kotlin
val scheduler = buildSchedule {
seconds {
at(5)
}
}
```
On the top of any `KronScheduler` currently there are several groups of extensions:
* Executes
* Shortcuts
* Flows
### Executes
All executes are look like `do...`. All executes are described below:
* `doOnce` - will get the next time for executing, delay until that time and call `block` with returning of the `block` result
* `doWhile` - will call `doOnce` while it will return `true` (that means that `block` must return `true` if it expects that next call must happen). In two words: it will run while `block` returning `true`
* `doInfinity` - will call the `block` using `doWhile` with predefined returning `true`. In two words: it will call `block` while it do not throw error
### Shortcuts
Shortcuts are the constants that are initializing in a lazy way to provide preset `KronScheduler`s. For more info about `KrontabScheduler` you can read its own [page](../describing/krontabscheduler.md).
* `AnyTimeScheduler` - will always return incoming `DateTime` as next
* `Every*Scheduler` - return near * since the passed `relatively`:
* `EverySecondScheduler`
* `EveryMinuteScheduler`
* `EveryHourScheduler`
* `EveryDayOfMonthScheduler`
* `EveryMonthScheduler`
* `EveryYearScheduler`
### Flows
Here currently there is only one extension for `KronScheduler`: `KronScheduler#asFlow`. As a result you will get `Flow<DateTime>` (in fact `SchedulerFlow`) which will trigger next `emit` on each not null `next` `DateTime`

View File

@ -0,0 +1,35 @@
# Including in project
In two words, you must add dependency `dev.inmo:krontab:$krontab_version` to your project. The latest version presented by next badge:
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab)
### Notice about repository
To use this library, you will need to include `MavenCentral` repository in you project
###### build.gradle
```groovy
mavenCentral()
```
### Dependencies
Next snippets must be placed into your `dependencies` part of `build.gradle` (for gradle) or `pom.xml` (for maven).
#### Gradle
```groovy
implementation "dev.inmo:krontab:$krontab_version"
```
#### Maven
```xml
<dependency>
<groupId>dev.inmo</groupId>
<artifactId>krontab</artifactId>
<version>${krontab_version}</version>
</dependency>
```

View File

@ -9,4 +9,4 @@ Anyway, the most important link is [How do I create a bot?](https://core.telegra
## Next steps
* [Including in your project](including-in-your-project.html)
* [Including in your project](including-in-your-project.md)

View File

@ -150,5 +150,5 @@ implementation "dev.inmo:tgbotapi.utils:$tgbotapi_version"
## Next steps
* [Proxy setup](proxy-setup.html)
* [First bot](first-bot.html)
* [Proxy setup](proxy-setup.md)
* [First bot](first-bot.md)

View File

@ -56,4 +56,4 @@ Explanation line by line:
## Next steps
* [First bot](first-bot.html)
* [First bot](first-bot.md)

View File

@ -10,7 +10,7 @@ There are several important things in context of this library:
* [Types](https://github.com/InsanusMokrassar/TelegramBotAPI/tree/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types)
* [Requests](https://github.com/InsanusMokrassar/TelegramBotAPI/tree/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests)
So, in most cases all your request calls with simplified api of this library (like `bot.getMe()`) will looks like `bot.execute(GetMe)`. Result of these calls is defined in type of any request (for example, for [GetMe](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/bot/GetMe.kt) request the result type is [ExtendedBot](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/Extended.kt#L101)). As a result, you can avoid any extension api (like [special API extensions](api-extensions.html)) and use low level request with full controlling of the whole logic flow.
So, in most cases all your request calls with simplified api of this library (like `bot.getMe()`) will looks like `bot.execute(GetMe)`. Result of these calls is defined in type of any request (for example, for [GetMe](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/bot/GetMe.kt) request the result type is [ExtendedBot](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/Extended.kt#L101)). As a result, you can avoid any extension api (like [special API extensions](api-extensions.md)) and use low level request with full controlling of the whole logic flow.
## How to handle updates
@ -24,4 +24,4 @@ Result type of [GetUpdates](https://github.com/InsanusMokrassar/TelegramBotAPI/b
## What is next?
As was said above, you may look into our [API extensions](api-extensions.html) in case you wish to use more high-level functions instead of `bot.execute(SomeRequest())`. Besides, it will be very useful to know more about [updates retrieving](../updates).
As was said above, you may look into our [API extensions](api-extensions.md) in case you wish to use more high-level functions instead of `bot.execute(SomeRequest())`. Besides, it will be very useful to know more about [updates retrieving](../updates).

View File

@ -2,7 +2,7 @@
> NOTE: **Preview reading**
>
> It is recommended to visit our pages about [UpdatesFilters](updates-filters.html) and [Webhooks](webhooks.html) to have more clear understanding about what is happening in this examples page
> It is recommended to visit our pages about [UpdatesFilters](updates-filters.md) and [Webhooks](webhooks.md) to have more clear understanding about what is happening in this examples page
[Heroku](https://heroku.com/) is a popular place for bots hosting. In common case you will need to configure webhooks for your server to include getting updates without problems. There are several things related to heroku you should know:
@ -11,7 +11,7 @@
* Currently (`Sat Aug 15 5:04:21 +00 2020`) there is only one official server engine for ktor which is correctly working with Heroku: [Tomcat server engine](https://ktor.io/servers/configuration.html#tomcat)
> NOTE: **Server configuration alternatives**
> Here will be presented variants of configuration of webhooks and starting server. You always able to set webhook manualy, create your own ktor server and include webhooks handling in it or create and start server with only webhooks handling. More info you can get on page [Webhooks](webhooks.html)
> Here will be presented variants of configuration of webhooks and starting server. You always able to set webhook manualy, create your own ktor server and include webhooks handling in it or create and start server with only webhooks handling. More info you can get on page [Webhooks](webhooks.md)
### Short example with Behaviour Builder

View File

@ -1,10 +1,10 @@
# Long polling
Long polling is a technology of getting updates for cases you do not have some dedicated server or you have no opportunity to receive updates via [webhooks](webhooks.html). More about this you can read in [wiki](https://en.wikipedia.org/wiki/Push_technology#Long_polling).
Long polling is a technology of getting updates for cases you do not have some dedicated server or you have no opportunity to receive updates via [webhooks](webhooks.md). More about this you can read in [wiki](https://en.wikipedia.org/wiki/Push_technology#Long_polling).
## Related topics
* [Updates filters](updates-filters.html)
* [Updates filters](updates-filters.md)
## Long polling in this library
@ -55,5 +55,5 @@ bot.startGettingOfUpdatesByLongPolling {
## See also
* [Webhooks](webhooks.html)
* [Updates filters](updates-filters.html)
* [Webhooks](webhooks.md)
* [Updates filters](updates-filters.md)

View File

@ -9,7 +9,7 @@ Due to the fact, that anyway you will get updates in one format (`Update` object
* `asUpdateReceiver` - required to represent this filter as common updates receiver which able to get any `Update`
* `allowedUpdates` - required to determine, which updates are usefull for this filter
Anyway, this filter can't work with updates by itself. For retrieving updates you should pass this filter to some of getting updates functions ([long polling](long-polling) or [webhooks](webhooks.html)).
Anyway, this filter can't work with updates by itself. For retrieving updates you should pass this filter to some of getting updates functions ([long polling](long-polling) or [webhooks](webhooks.md)).
### SimpleUpdatesFilter
@ -119,5 +119,5 @@ flowsUpdatesFilter {
## See also
* [Long polling](long-polling.html)
* [Webhooks](webhooks.html)
* [Long polling](long-polling.md)
* [Webhooks](webhooks.md)

View File

@ -122,5 +122,5 @@ In the example above server will started and binded for listening on `0.0.0.0:80
## See also
* [Updates filters](updates-filters.html)
* [Long polling](long-polling.html)
* [Updates filters](updates-filters.md)
* [Long polling](long-polling.md)

View File

@ -21,6 +21,14 @@ nav:
- 'tgbotapi/updates/heroku.md'
- Logic handling: 'tgbotapi/logic/'
- DSLs: 'tgbotapi/dsls/'
- 'Krontab':
- Introduction:
- 'krontab/introduction/including-in-project.md'
- 'krontab/introduction/how-to-use.md'
- 'krontab/introduction/faq.md'
- Describing:
- 'krontab/describing/string-format.md'
- 'krontab/describing/krontabscheduler.md'
use_directory_urls: false