Μετάβαση στο περιεχόμενο

Συχνές Ερωτήσεις

Όχι. Κάθε instance εκτελεί τον ίδιο κώδικα. Για κάθε εκτέλεση, όλα ρωτούν το κοινόχρηστο store, και το store επιτρέπει σε ένα μόνο να κερδίσει. Δεν υπάρχει τίποτα προς εκλογή και τίποτα προς αποδέσμευση.

Πώς διαφέρει αυτό από μια απλή βιβλιοθήκη cron;

Ενότητα με τίτλο «Πώς διαφέρει αυτό από μια απλή βιβλιοθήκη cron;»

Μια βιβλιοθήκη cron όπως το croner πυροδοτεί ένα χρονόμετρο στη διεργασία στην οποία εκτελείται. Με τρία instances, η εργασία εκτελείται τρεις φορές. Το anarchon προσθέτει το βήμα που επιλέγει ένα instance: μια ατομική διεκδίκηση σε ένα store που μοιράζονται όλα τα instances. Χρησιμοποιεί το croner μόνο για να υπολογίσει πότε αναμένεται να εκτελεστεί μια έκφραση cron.

Το node-cron μπορεί επίσης να επιλέξει έναν runner ανά προγραμματισμένο χρόνο με την επιλογή distributed. Η σελίδα Επιλέγοντας το anarchon συγκρίνει τα δύο, καθώς και το BullMQ και τα Kubernetes CronJobs.

Πώς διαφέρει αυτό από μια ουρά εργασιών;

Ενότητα με τίτλο «Πώς διαφέρει αυτό από μια ουρά εργασιών;»

Μια ουρά διανέμει πολλά κομμάτια εργασίας σε workers. Το anarchon αποφασίζει ποιο instance εκτελεί μια εργασία σε κάθε προγραμματισμένο χρόνο. Συνδυάζονται άριστα: μια προγραμματισμένη εργασία μπορεί να τοποθετήσει εργασίες σε μια ουρά.

Μπορώ να το χρησιμοποιήσω με ένα μόνο instance;

Ενότητα με τίτλο «Μπορώ να το χρησιμοποιήσω με ένα μόνο instance;»

Ναι. Συμπεριφέρεται σαν ένας κανονικός scheduler, και έχετε ιστορικό, καθώς και προστασία αλληλεπικάλυψης και ανάκτηση μετά από επανεκκινήσεις σε backend μίσθωσης. Είναι επίσης έτοιμο για τη μέρα που θα προσθέσετε ένα δεύτερο instance.

Node.js 20 και νεότερο. Ο ενσωματωμένος οδηγός SQLite απαιτεί Node 22.13 (ή 22.5 με το flag --experimental-sqlite)· σε παλαιότερες εκδόσεις χρησιμοποιήστε το better-sqlite3 (έκδοση 12 στο Node 20).

Γιατί η εργασία μου εκτελέστηκε κατά την εκκίνηση, εκτός του προγράμματός της;

Ενότητα με τίτλο «Γιατί η εργασία μου εκτελέστηκε κατά την εκκίνηση, εκτός του προγράμματός της;»

Αυτό είναι η ανάκτηση: η τελευταία θυρίδα έπρεπε να εκτελεστεί πρόσφατα και κανείς δεν την είχε εκτελέσει, για παράδειγμα αμέσως μετά από πλήρη επανεκκίνηση. Ορίστε catchUpMs: 0 στην εργασία για να την απενεργοποιήσετε.

Γιατί μια εργασία εμφανίζει skipped (taken) στα περισσότερα instances;

Ενότητα με τίτλο «Γιατί μια εργασία εμφανίζει skipped (taken) στα περισσότερα instances;»

Επειδή ένα instance κέρδισε την εκτέλεση και τα υπόλοιπα όχι. Με τρία instances, δύο παραλείψεις ανά εκτέλεση είναι το φυσιολογικό.

Γιατί μια εκτέλεση παραλείφθηκε ως overlap;

Ενότητα με τίτλο «Γιατί μια εκτέλεση παραλείφθηκε ως overlap;»

Η προηγούμενη εκτέλεση αυτής της εργασίας βρισκόταν ακόμη σε εξέλιξη. Οι εκτελέσεις μιας εργασίας δεν αλληλεπικαλύπτονται εκτός εάν ορίσετε overlap: 'allow'.

Επαναλαμβάνεται μια αποτυχημένη εργασία;

Ενότητα με τίτλο «Επαναλαμβάνεται μια αποτυχημένη εργασία;»

Όχι. Ένας handler που ρίχνει σφάλμα καταγράφεται ως failed, και η επόμενη εκτέλεση είναι η επόμενη προγραμματισμένη θυρίδα. Οι επαναλήψεις προορίζονται για runners που καταρρέουν, όχι για σφάλματα. Επαναλάβετε τα σφάλματα μέσα στον handler σας εάν το επιθυμείτε.

Μπορεί μια εργασία να εκτελεστεί δύο φορές για την ίδια θυρίδα;

Ενότητα με τίτλο «Μπορεί μια εργασία να εκτελεστεί δύο φορές για την ίδια θυρίδα;»

Ναι, όταν ο runner της καταρρεύσει ή παγώσει κατά τη διάρκεια της εκτέλεσης και ένα εφεδρικό instance την ξεκινήσει ξανά. Χρησιμοποιήστε το ctx.slot ως κλειδί αναγνώρισης μοναδικότητας. Δείτε Εγγυήσεις και όρια.

await scheduler.runNow('name'). Εκτελείται στο instance στο οποίο την καλείτε, δεν αποδιπλασιάζεται, και καταγράφεται ως χειροκίνητη εκτέλεση.

Μπορώ να αλλάξω το πρόγραμμα μιας εργασίας χωρίς επανεκκίνηση;

Ενότητα με τίτλο «Μπορώ να αλλάξω το πρόγραμμα μιας εργασίας χωρίς επανεκκίνηση;»

scheduler.remove('name'), και στη συνέχεια προσθέστε την ξανά με το νέο πρόγραμμα. Κάντε το σε κάθε instance.

Μπορούν να προστεθούν εργασίες μετά το start();

Ενότητα με τίτλο «Μπορούν να προστεθούν εργασίες μετά το start();»

Ναι. Προγραμματίζονται αμέσως.

Οι handlers είναι συνηθισμένες συναρτήσεις, οπότε μπορούν να χρησιμοποιήσουν closures για ό,τι χρειάζονται. Για δεδομένα που αποφασίζετε εκεί όπου ορίζεται η εργασία ή ο scheduler, όπως ένα δικαίωμα, έναν tenant ή ένα φρέσκο token, δώστε ένα data και διαβάστε το ως ctx.data. Δεν υπάρχει payload ανά εκτέλεση από άλλο instance, επειδή μια εκτέλεση ορίζεται από τον χρόνο της, όχι από ένα μήνυμα.

Μπορώ να δηλώσω εργασίες με decorators, όπως στο NestJS;

Ενότητα με τίτλο «Μπορώ να δηλώσω εργασίες με decorators, όπως στο NestJS;»

Ναι, με τα @Every, @Cron και @At πάνω στις μεθόδους οποιασδήποτε κλάσης, με ή χωρίς framework. Ένα αντικείμενο προσθέτει τις εργασίες του στον scheduler όταν δημιουργείται, οπότε δεν χρειάζεται καμία καταχώριση. Δείτε Decorators.

Πρέπει να δημιουργήσω scheduler για να χρησιμοποιήσω τους decorators;

Ενότητα με τίτλο «Πρέπει να δημιουργήσω scheduler για να χρησιμοποιήσω τους decorators;»

Όχι. Δώστε τις ρυθμίσεις μία φορά με το Scheduler.configure({ backend: new RedisBackend({ redis: url }), autoStart: true }), και ο scheduler δημιουργείται και ξεκινά όταν δημιουργηθεί το πρώτο αντικείμενο με decorators. Το backend πρέπει να υπάρχει στις ρυθμίσεις· δεν υποτίθεται κανένα. Δείτε Decorators.

Μπορούν διαφορετικές εργασίες να χρησιμοποιούν διαφορετικούς schedulers;

Ενότητα με τίτλο «Μπορούν διαφορετικές εργασίες να χρησιμοποιούν διαφορετικούς schedulers;»

Ναι. Ένας decorator ονομάζει έναν με το { scheduler: 'billing' }, και οι εργασίες με το ίδιο όνομα τον μοιράζονται. Δείτε Επιλογή scheduler για μια εργασία.

Μπορώ να έχω πολλά αντικείμενα μιας κλάσης με decorators;

Ενότητα με τίτλο «Μπορώ να έχω πολλά αντικείμενα μιας κλάσης με decorators;»

Ναι, το καθένα με δικό του πρόθεμα: scheduler.register(new Reports(), { prefix: 'acme:' }). Δείτε Πολλά αντικείμενα μιας κλάσης.

Γιατί η εργασία μου με decorator δεν εκτελείται ποτέ;

Ενότητα με τίτλο «Γιατί η εργασία μου με decorator δεν εκτελείται ποτέ;»

Αναζητήστε στην έξοδο του start() μια προειδοποίηση που ξεκινά με [anarchon] @Every ... is not scheduled: ο scheduler δίνει μία για κάθε δηλωμένη εργασία που κανένα αντικείμενο δεν έχει προσθέσει, και εξηγεί τον λόγο.

Συνήθως το project γίνεται compile με legacy decorators ("experimentalDecorators": true) και η κλάση δεν έχει @Scheduled(). Σε αυτό το στυλ ένας decorator μεθόδου δεν μπορεί να ενεργήσει όταν δημιουργείται ένα αντικείμενο, οπότε προσθέστε το @Scheduled() στην κλάση ή καλέστε το scheduler.register(object). Η άλλη αιτία είναι ότι δεν δημιουργείται καθόλου αντικείμενο της κλάσης. Το scheduler.jobs() δείχνει τι προστέθηκε.

Τι σημαίνει η προειδοποίηση ANARCHON_DUPLICATE_COPY;

Ενότητα με τίτλο «Τι σημαίνει η προειδοποίηση ANARCHON_DUPLICATE_COPY;»

Το anarchon είναι εγκατεστημένο δύο φορές στην εφαρμογή σας, συνήθως επειδή μια εξάρτηση ζητά άλλη έκδοση. Κάθε αντίγραφο έχει τη δική του λίστα από schedulers, οπότε οι εργασίες που δηλώνονται με τους decorators του ενός δεν προστίθενται ποτέ σε scheduler του άλλου. Το npm ls anarchon (ή pnpm why anarchon) δείχνει από πού προέρχονται τα αντίγραφα· κάντε τα να καταλήγουν σε μία έκδοση.

Ένα timeout μετρά από την εκκίνηση κάθε διεργασίας, οπότε κάθε instance θα υπολόγιζε διαφορετικό χρόνο και θα εκτελούσε την εργασία. Το @At δέχεται έναν απόλυτο χρόνο στον οποίο συμφωνούν όλα τα instances.

Εκτελείται το every('1d') τα μεσάνυχτα στη δική μου ώρα;

Ενότητα με τίτλο «Εκτελείται το every('1d') τα μεσάνυχτα στη δική μου ώρα;»

Όχι, τα μεσάνυχτα UTC. Χρησιμοποιήστε cron('0 0 * * *', handler, { timezone: 'Europe/Athens' }) για τοπική ώρα.

Γιατί η εργασία μου δεν ξεκινά ακριβώς στο δευτερόλεπτο;

Ενότητα με τίτλο «Γιατί η εργασία μου δεν ξεκινά ακριβώς στο δευτερόλεπτο;»

Κάθε instance περιμένει μια τυχαία καθυστέρηση έως και jitterMs (2 δευτερόλεπτα από προεπιλογή) πριν διεκδικήσει, ώστε να κατανεμηθεί το φορτίο. Ορίστε jitterMs: 0 για εκκίνηση ακριβώς στην ώρα· το ταχύτερο instance θα κερδίζει τότε κάθε φορά.

Πόσο γρήγορα αντικαθίσταται ένας νεκρός runner;

Ενότητα με τίτλο «Πόσο γρήγορα αντικαθίσταται ένας νεκρός runner;»

Εντός leaseMs + 2 × heartbeatMs: 40 δευτερόλεπτα με τις προεπιλογές. Μειώστε το leaseMs για ταχύτερο failover.

Τι γίνεται αν τα ρολόγια των instances μου διαφέρουν;

Ενότητα με τίτλο «Τι γίνεται αν τα ρολόγια των instances μου διαφέρουν;»

Μια μικρή διαφορά αλλάζει μόνο ποιο instance τείνει να κερδίζει. Οι μισθώσεις χρησιμοποιούν το ρολόι του store, επομένως δεν επηρεάζονται. Διατηρείτε τα ρολόγια συγχρονισμένα με NTP.

Το store που έχετε ήδη. Το Redis, το PostgreSQL και το SQLite προσφέρουν το πλήρες σύνολο δυνατοτήτων. Το RabbitMQ και το NATS εγγυώνται μόνο έναν νικητή ανά εκτέλεση. Δείτε Επισκόπηση backends.

Μπορούν δύο υπηρεσίες να μοιράζονται το ίδιο Redis ή βάση δεδομένων;

Ενότητα με τίτλο «Μπορούν δύο υπηρεσίες να μοιράζονται το ίδιο Redis ή βάση δεδομένων;»

Ναι, με διαφορετικό prefix (Redis, RabbitMQ, NATS) ή table (PostgreSQL, SQLite) η καθεμία. Δείτε Πολλαπλές υπηρεσίες σε ένα store.

Κλείνει το anarchon τον Redis client ή το database pool μου;

Ενότητα με τίτλο «Κλείνει το anarchon τον Redis client ή το database pool μου;»

Όχι. Κλείνει μόνο τις συνδέσεις που άνοιξε το ίδιο.

Τι συμβαίνει εάν το store είναι εκτός λειτουργίας;

Ενότητα με τίτλο «Τι συμβαίνει εάν το store είναι εκτός λειτουργίας;»

Καμία εκτέλεση δεν μπορεί να διεκδικηθεί, οπότε οι προγραμματισμένες εκτελέσεις παραλείπονται σε κάθε instance, με συμβάντα error. Οι εργασίες που εκτελούνται ήδη συνεχίζονται. Όταν το store επανέλθει, ο προγραμματισμός συνεχίζεται, και σε ένα backend μίσθωσης η τελευταία χαμένη εκτέλεση ανακτάται εάν βρίσκεται εντός του catchUpMs.

Η στρατηγική lease τοποθετεί όλα τα κλειδιά μιας εργασίας κάτω από το ίδιο hash tag, ώστε τα scripts της να εκτελούνται σε έναν μόνο κόμβο. Περάστε έναν cluster client που έχετε δημιουργήσει εσείς. Οι ενσωματωμένες δοκιμές εκτελούνται σε μεμονωμένους διακομιστές.

Μπορώ να χρησιμοποιήσω SQLite σε πολλαπλά μηχανήματα;

Ενότητα με τίτλο «Μπορώ να χρησιμοποιήσω SQLite σε πολλαπλά μηχανήματα;»

Όχι με απλό αρχείο. Χρησιμοποιήστε έναν διακομιστή libSQL ή Turso, ή PostgreSQL.

Πώς κάνω καθαρό τερματισμό κατά τη διάρκεια deploy;

Ενότητα με τίτλο «Πώς κάνω καθαρό τερματισμό κατά τη διάρκεια deploy;»

Καλέστε await scheduler.stop() στο SIGTERM, και φροντίστε οι handlers να ρίχνουν σφάλμα όταν ακυρώνεται το ctx.signal. Η εκτέλεση παραδίδεται σε άλλο instance. Δείτε Rolling deploys στο Kubernetes.

Το scheduler.history('name') επιστρέφει τις εκτελέσεις από όλα τα instances. Το log: true εκτυπώνει μία γραμμή ανά συμβάν σε κάθε instance.

Μετρήστε τα συμβάντα failure, lost και τα συμβάντα skip που δεν είναι taken ως μετρικές, και θέστε ειδοποιήσεις εάν το lastRun() είναι πολύ παλιό ή απέτυχε. Δείτε Συμβάντα και καταγραφή.

Ανά εκτέλεση: μία διεκδίκηση ανά instance, ένα heartbeat κάθε heartbeatMs από τον runner, ένας έλεγχος κάθε ένα έως δύο heartbeats από κάθε εφεδρικό instance, και δύο εγγραφές στο τέλος. Για τις περισσότερες υπηρεσίες αυτό αντιστοιχεί σε μια χούφτα μικρών λειτουργιών ανά εργασία ανά λεπτό.

Τα κλειδιά, οι πίνακες και οι μορφές μηνυμάτων είναι εσωτερικά και ενδέχεται να αλλάξουν μεταξύ εκδόσεων. Διαβάζετε μέσω του history().

Το anarchon διαθέτει διπλή άδεια χρήσης: GNU AGPLv3, ή εμπορική άδεια για εφαρμογές που δεν μπορούν να διατεθούν υπό την AGPL. Τα αρχεία LICENSE και COMMERCIAL_LICENSE.txt του repository περιέχουν τους όρους, και η σελίδα Άδειες χρήσης τους συνοψίζει: τις κλίμακες εσόδων, την εγγραφή στη δωρεάν κλίμακα και την επικοινωνία.