Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπερα.

 

Παρτε popcorn.

 

Χρησιμοποιωντας το Node.js εδω και καιρο διαβασα οτι το I/O ειναι non-blocking και δεν το εψαξα παραπανω. Με τα αρθρα εναντιον του Node να αυξανονται , διαβασα καποια πραγματα που το μαιμουδισιο κεφαλακι μου δε μπορει να κατανοησει πληρως και γ'αυτο ζηταω λιγο τη βοηθεια σας.

 

Τα αρθρα που διαβασα και προσπαθησα να καταλαβω

Link.png Site: https://medium.com/@theflapjack103/the-way-of-the-gopher-6693db15ae1f#.c0240dnwl

και 

Link.png Site: http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/

 

Αν καταλαβα καλα

 

> Το node ειναι single-thread επειδη (i) ειναι η javascript και (ii) ετσι αποφευγει ολα τα αρνητικα του multi-thread

 

> Για να κανει πολλα πραγματα μαζι και ας ειναι single-thread χρησιμοποιει asynchronous call-backs, οποτε οντως το I/O του ειναι non-blocking. Πχ το να μιλησει με τη βαση και να παρει 10 αποτελεσματα ειναι non-blocking.

 

> Αλλα , οι ειδοποιησεις για να τρεξει κατι Ι/Ο non-blocking και τα αποτελεσματα αυτου του non-blocking που θα πρεπει να πανε στον client , αυτα συνεχιζουν να πηγαινοερχονται μεσα απο ενα single-thread. Για να παρει ολες τις ειδοποιησεις και να στειλει πισω αποτελεσματα, το node χρησιμοποιει το "event loop"  μεσα στο single-thread. Το event loop λοιπον μπορει να ειναι blocking αμα εμφανιστουν ταυτοχρονα πολλες περιπλοκες ειδοποιησεις.

 

Μαλλον δεν εχω καταλαβει καλα τι παιζει μιας και στα αρθρα τοινιζουν οτι "Node is single-threaded which means none of your code runs in parallel". Οποτε το προβλημα ειναι στον κωδικα και οχι στο event-loop? Μα, ειπαμε οτι ο κωδικας ειναι non-blocking.

 

(α) Θελω να ξεκαθαρισω σε ποιο σημειο ακριβως και σε ποια περιπτωση ο node γινετε blocking. 

 

επισης

(β) το event-loop τρεχει μονιμα προσπαθωντας να βρει καποια ειδοποιηση ή ενεργοποιειται οταν ερθει καποια ειδοποιηση?

 

 

Ευχαριστω πολυ

 

Δημοσ.

Καλή ερώτηση, δεν μπορώ να συμπτήξω ούτε να απλοποιήσω αυτά που θα διαβάσεις εδώ αλλά ίσως σε καλύψουν.

 

Όχι ότι είμαι expert ή κάτι τέτοιο αλλά νομίζω πως αν (ξανα?)διαβάσεις γενικότερα concept async javascript και τι ακριβώς είναι το event loop στην js, θα έχεις αρκετά aha moments

Δημοσ.

Η λέξη "blocking" σ' αυτό το context έχει μια πολύ συγκεκριμένη σημασία, αυτό να το ξεκαθαρίσουμε από την αρχή.

 

Έστω μια I/O bound διεργασία την οποία θέλουμε να πραγματοποιήσουμε. Φανερά εφόσον είναι I/O bound, η CPU θα έχει χρόνο να σκοτώσει μέχρι να ολοκληρώσουν τη δουλειά τους οι αδύναμοι κρίκοι της διεργασίας. Ο τρόπος με τον οποίο επιλέγουμε να πραγματοποιήσουμε τη διεργασία λοιπόν λέγεται blocking αν τα κάνουμε έτσι ούτως ώστε η CPU να παίζει με το στανιό τα βλέφαρά της μέχρι να ολοκληρωθεί η υπόλοιπη δουλειά, και non-blocking αν η CPU είναι ελεύθερη να ασχοληθεί με άλλα πράγματα στο ενδιάμεσο.

 

Παρόλο που με τον περιορισμό σε I/O bound παραπάνω είναι ευκολότερο να εξηγήσει κανείς τι συμβαίνει, εντούτοις στην πραγματικότητα η ίδια ορολογία χρησιμοποιείται και για cpu-bound tasks. Αυτό συνήθως δεν έχει νόημα όταν μιλάμε για ένα σύστημα που είναι τελείως single-threaded όπως το node -- τουλάχιστον σε multithreaded σύστημα μπορεί κανείς να παρατηρήσει ότι δεν υπάρχει "η (μία) CPU" που λέω παραπάνω οπότε είναι φανερό από πού ανοίγει το παραθυράκι για να χρησιμοποιείται διαφορετικά ο όρος -- μιας και blocking or not, αφού έχεις μία CPU και αυτή θα πρέπει να κάνει τα πάντα όσο και να χτυπιέσαι αύξηση επιδόσεων μέσω αποφυγής αδράνειας της CPU δεν πρόκειται να δεις. Αλλά το να προσποιείσαι ότι πράγματα που στην ουσία είναι blocking είναι και καλά non-blocking έχει μεγάλη σημασία στον τρόπο με τον οποίο αντιμετωπίζει το σύστημα ο προγραμματιστής, όπως π.χ. το γεγονός ότι είχαμε "multitasking" ακόμα και πριν υπάρξουν dual core CPUs δεν αλλάζει την ουσία πως αν έβαζες κάτι να τρώει 100% CPU σου γονάτιζε το σύστημα, αλλάζει όμως πολύ το πώς αντιμετωπίζει το σύστημα ο χρήστης του (παίζει μουσική και κατεβάζω και βλέπω βίντεο ταυτόχρονα).

 

 

 

Υπάρχει και τουλάχιστον μία ακόμα διαφορετική και διαδεδομένη σημασία του (non) blocking, όταν έχουμε να κάνουμε με συστήματα που έχουν σχέση producer/consumer (π.χ. διάβασμα δεδομένων από socket όπου μπορεί να υπάρχουν ή να μην υπάρχουν δεδομένα προς ανάγνωση όταν το ζητήσουμε). Εκεί το blocking έχει την έννοια "θα περιμένει ο consumer πότε θα δεήσει ο producer να μας δώσει αυτά που ζητήσαμε, ή θα επιστρέψει το call αμέσως με απάντηση σόρι το προϊόν δεν είναι σε στοκ και δεν ξέρω πότε θα ξαναέχουμε"? Υπόψη για να μη μπερδευόμαστε, είναι τελείως άσχετα μεταξύ τους πράγματα. Στη συνέχεια όταν λέω (non) blocking εννοώ πάντα με τον ορισμό της πρώτης παραγράφου.

 

 

 

Οι non-blocking υλοποιήσεις προφανώς χρειάζονται κάποιον τρόπο για να ειδοποιήσουν τον κώδικα που θα πάρει τα αποτελέσματα όταν είναι διαθέσιμα πως ήρθε η στιγμή. Υπάρχουν διάφοροι τρόποι για να το κάνει αυτό κανείς, από σχετικά απλούς αλλά με χειρότερες σχετικά επιδόσεις, μέχρι ειδικούς OS-specific τρόπους, μέχρι περίπλοκες manual τεχνικές που χρησιμοποιούνται εκεί που χρειάζεται μέγιστη απόδοση (π.χ. εσωτερικά σε ένα database server).

 

Νομίζω ότι η ερώτησή σου βασικά ξεκινάει από το ότι δεν έχεις ξεκάθαρη ιδέα του τι σημαίνει "blocking":

 

Για να παρει ολες τις ειδοποιησεις και να στειλει πισω αποτελεσματα, το node χρησιμοποιει το "event loop"  μεσα στο single-thread. Το event loop λοιπον μπορει να ειναι blocking αμα εμφανιστουν ταυτοχρονα πολλες περιπλοκες ειδοποιησεις.

 

 

Δεν θα είναι blocking αλλά CPU-bound. Προφανώς αν κάνεις 115 async πράγματα και επιστρέψουν όλα μαζί, δεν είναι δυνατό να ενημερώσεις ταυτόχρονα και τους 115 "πελάτες" ότι τα δεδομένα τους έφτασαν. Αυτό δε σημαίνει πως ο μηχανισμός παραλαβής δεδομένων και προώθησης στους πελάτες (στην προκειμένη περίπτωση το event loop) είναι blocking. Οποιοδήποτε κομμάτι κώδικα έχει υποχρέωση να κάνει 115 πράγματα προφανώς θα πρέπει να τα κάνει ένα ένα με κάποια σειρά.

 

Ελπίζω να βοήθησα.  :)

  • Like 1
Δημοσ.

Για να τσεκαρω αν καταλαβα

 

Το node ειναι single-threated. Αυτο σημαινει οτι ο κωδικας που γραφεις δεν μπορει να τρεξει παραλληλα, αλλα οι Ι/Ο συναλλαγες μπορουν, τις κανουμε concurrency μεσα απο asynchronous javascript functions, αυτο το ονομαζουν non-blocking. 

 

Node.js keeps a single thread for your code......however, everything runs in parallel, except your code.

Doing a "sleep" for example will block the server for one second. - single-threated κωδικας

All I/O is evented and asynchronous, so the following won't block the server: c.query( 'SELECT SLEEP(20);', .... - ειναι μεσα σε asynchronous function, το query δηλαδη - non-blocking I/O

απο εδω(Link.png Site: http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/ )

 

Για να διαχειριστει τα requests που ερχονται μεσα, ο Node εχει το event loop. Το event loop πιανει τα request και τα μετατρεπει/αντιστοιχει σε callbacks γιατι οι asynchronous Ι/Ο javascript functions εχουν callbacks. Ξεκιναει ενα asynchronous Ι/Ο javascript function και γυρναει τον ελεγχο πισω στο Node. Το node ξεκιναει το επομενο  asynchronous Ι/Ο function. To callback τις καθε function θα καλεστει οταν η function εχει να απαντησει κατι (βρηκα αυτο, η ταδε πραξη κανει τοσο κτλ). Το I/O ειναι non-blocking γιατι οσο εκτελειται ενα I/O , o node μπορει να κανει κατι αλλο αντι να περιμενει.(απο το κομματι 

Why is this good? When do we go from sync to async/parallel execution? στο Link.png Site: http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/ )

 

Τωρα, αν εντοπισει ο node ενα request που ειναι βαρυ και θα παρει πολυ ωρα να απαντησει κατι, του ανοιγει ενα δικο του thread. Ο κωδικας σου παραμενει single-threat, το νεο thread ειναι για το βαρυ request οχι για τον κωδικα η ολο το server. Αυτο το thread λοιπον φτιαχνει ενα callback και οταν υπαρχει μια απαντηση, αυτη μεσω του callback ξαναγυρναει στο event loop. Απο το event loop πισω στον client. (απο εδω Link.png Site: http://www.journaldev.com/7462/node-js-processing-model-single-threaded-model-with-event-loop-architecture )

 

1- Αν υπαρχουν πολλα μικρα requests δεν υπαρχει προβλημα γιατι δεν περνουν πολυ χρονο, ειναι ολα non-blocking και ολα γινονται γρηγορα. 

 

Απο δω και κατω παιζει να μη τα καταλαβαινω σωστα.

 

2- Αν υπαρχουν πολλα μικρα requests και ενα βαρυ και ειναι ολα μεσα σε asynchronous functions, ωστε να ισχυει το non-blocking. Τα μικρα επιστρεφουν γρηγορα και το βαρυ θα αργησει μεσα στο δικο του thread και οχι ολο τον node. Ειπαμε οτι λογω non-blocking ο node δε καθεται να περιμενει, οποτε οτι απαντησει πρωτο το γυρναει στον client. Τα πιο πολλα μικρα θα απαντησουν πρωτα και το βαρυ θα αργησει, οπως ειναι λογικο. Βεβαια επειδη στο event-loop ολα μπαινουν και βγαινουν με μια σειρα (FIFO νομιζω) , ολες οι callbacks των μικρων request που ειναι μετα το βαρυ request θα καθυστερησουν γιατι το βαρυ καθυστερει κ αυτα ειναι πισω του. Σα τη κινηση στο δρομο, αν εγω θελω 1 λεπτο να παω καπου , αλλα κολλησα πισω απο εναν που παει αργα, θα θελω 5 λεπτα τελικα και οχι ενα. Τhe callback wasn’t getting processed until all other messages currently on the queue, and their corresponding callback code, were finished executing (potentially seconds later). Απο εδω ( Link.png Site: https://medium.com/@theflapjack103/the-way-of-the-gopher-6693db15ae1f#.r5q4lm89w  )

 

3- Αν υπαρχουν πολλα βαρια requests και ειναι ολα μεσα σε asynchronous functions, ωστε να ισχυει το non-blocking. Εκει θα κολλησουν ολα. Καταρχας επειδη, I/O may not block the server but your code certainly does (single-threated, synchronous) μπορει να γινει το εξης. 

Βαρυ request, ανοιξε του thread, παμε στο επομενο, βαρυ request, ανοιξε του thread, παμε στο επομενο, 100 φορες. Αν καθε ενα περνει το λιγοτερο 1 δευτερολεπτο να απαντησει, τοτε μαζευεται πολυς χρονος. Το καθενα καθυστερει στο thread του, αλλα αθροιζονται στον single-threated node που βασιζεται στο event loop. Γιατι καθε βαρυ callback που αργει , κολλαει πισω απο ενα αλλο βαρυ callback που αργει.

 

4- Το 3 περιγραφει και το προβλημα της Grant εδω Link.png Site: https://medium.com/@theflapjack103/the-way-of-the-gopher-6693db15ae1f#.r5q4lm89w . Αυτο ηταν και το αρθρο που μου κινησε τη περιεργια να μαθω παραπανω ποτε κολλαει ο node.

Our Node service may have handled incoming requests like champ if all it needed to do was return immediately available data. 

Αλλα ισχυει οτι Node is single-threaded which means none of your code runs in parallel. I/O may not block the server but your code certainly does. If I call sleep for 5 seconds, my server will be unresponsive during that time.

Η τυπισσα γεμισε με πολλα βαρια requests αν και δεν εφταιγε αποκλειστικα ο Node επειδη εξαρτιοταν απο ενα service του amazon,  επειδη was waiting on a ton of nested callbacks all dependent on responses from S3 (which can be god awful slow at times)

Και μετα ηρθε και το event loop και κολλησαν ολα In a loop, the queue is polled for the next message (each poll referred to as a “tick”) and when a message is encountered, the callback for that message is executed. The calling of this callback function serves as the initial frame in the call stack, and due to JavaScript being single-threaded, further message polling and processing is halted pending the return of all calls on the stack. Subsequent (synchronous) function calls add new call frames to the stack... ...... when any request timeouts happened, the event and its associated callback was put on an already overloaded message queue. While the timeout event might occur at 1 second, the callback wasn’t getting processed until all other messages currently on the queue, and their corresponding callback code, were finished executing (potentially seconds later).

 

Δε ξερω ποιος ηρωας θα κατσει να το διαβασει ολο αυτο, αλλα αν θελετε να βοηθησετε η να με διορθωσετε, πειτε μου. Ευχαριστω πολυ και παλι

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...