Placeholder Image

字幕列表 影片播放

  • Ah, this begin.

  • Ah, Good morning, everyone.

  • So today I'm going to talk about race conditions in JavaScript caps on dhe.

  • So write a title off this talk.

  • It's about race conditions.

  • Today, I'm going to talk about other things as well.

  • Maybe other age cases that are not strictly rest conditions.

  • But you may encounter them when you write, I think, when this coat.

  • So before I begin to talk, I would like to share a bit off story before like how this talk came to be so I first got the idea off for this talk.

  • Um, on one day on that day, I went to ah local meet up in Thailand, and after the talks are done, it's like networking time.

  • And my friend approached me and asked me, Hey, Ty, is it hot to do with race conditions in JavaScript?

  • So I answered, Well, is actually pretty easy.

  • You just don't forget about them.

  • She gives me a bit off confused look, and I was like, Hey, I'm totally serious here.

  • Let me show you a couple of examples.

  • So I got my laptop and start courting, showing him some examples on dhe.

  • Before long, it turned into a really deep discussion.

  • So after that discussion, my friend told me Well, this could have bean Ah, food talk.

  • Ah, why don't you make a top outfit and somebody to just con for something?

  • So here I am.

  • And a big shout out goes to game for giving me the inspiration for this talk.

  • Ah Hughes, with us here as well.

  • So next time you have deep technical discussion, maybe you can tell your friend to, like consider something a talk.

  • So this makes it my second time speaking here at just con facia.

  • So Ah, big, big things to Thomas and all the organizer's involved in running this conference.

  • It's really great on Thank you for having me once again.

  • So today I'm going to show you two stories for my experience dealing with race conditions and stuff.

  • So I hope you can learn something out off these stories that I did.

  • By the way, my name is tie in from Thailand.

  • My twitter handle Oh, is at DT ai nts.

  • And if you have any feedback about this talk, please send it to me and I would really appreciate it.

  • I'm currently working at Tasco as their front an architect, and I'll get back to that later.

  • But now here comes.

  • The first story on this story involves a little search box.

  • So in this search, boss aside, type of key word is going to show the source result on dhe.

  • It's going to show the result instantly, so I don't have to press enter or anything.

  • It's like glucose auto suggests, so let's build this real quick.

  • First we need the markup.

  • So, yes, I'm going to use a section for the rapper than doesn't input boss right there and then list containing the result.

  • So that's how the markup we need.

  • Next we going to add some interactivity, and for that I'm going to use real Js.

  • So let's start with the data model for our state.

  • First, we need to start there so security that they use the type and we can buy that today input boss, using the we model directive.

  • Then we also need to start the first result to be displayed on the list here on Dhe.

  • To do that, we can use the wi for directive to do the biting, and finally we buy the content off its result into the respective elements so that the data and the dumb they're now kept in sync.

  • So when the user enters the test, Curie in Tudor input feel is going to update the text right here on dhe.

  • We can wash for when it changes and when it changes, we can perform in a synchronous curie by calling the thirst function right there.

  • It's going to return a promise.

  • So we have to await it.

  • And once the result arrived, reserve it into the state, which will be displayed onto you.

  • Think the face so that we have it on.

  • Let's see how it goes.

  • So okay, I'm going to type in react.

  • I don't know why, but Okay.

  • Ah, so the result shows up, and that's good, but it seems that door is so that I see here doesn't have anything to do with react.

  • So what's going on here?

  • Uh, let's try again.

  • But this time I built an inspector on the right so that we can see what's going on.

  • Okay.

  • Ah, you can see here that dirty thought I I want to see is overwritten by the results off the requests that I made earlier but it finished later.

  • So it all right there the dumb on Dhe.

  • You know, this kind of makes sense because the shorter the curie, maybe it will return modest out.

  • And maybe it will take longer to load.

  • So you cannot depend on the other off the request to correspond to the order of the response.

  • So you can think off and I think function as they ah, function that spawns the trade.

  • And Dom here is a sharp, mutable state.

  • So, you know, when dealing with shot mutable state, we have to be Cafu.

  • So let's come back to this coat when we face problem like this one off.

  • The common opposed I see very often is to do Ah, the bounce.

  • And what I mean by de bouncing Is that inside off doing the search right away?

  • We're going to wait a bit until the use of has finished typing.

  • And after that period off in activity, then we do the search as usual.

  • So let's try it.

  • Okay?

  • It seems to work because now it only performs a single request.

  • There are no more computing request.

  • But, you know, even with the bounce, it still doesn't guarantee the order off the response so I could do something like this.

  • Then we're back to the same problem.

  • So let's step back and look at this court again.

  • The real problem here Is that why we're waiting for the results to arrive?

  • I could have triggered another search.

  • And in this case, when the result did arrive, it might not make sense to use that anymore.

  • Because now I I have already triggered another third.

  • So let's fish this.

  • But first, I'm going to get rid off the D bounce because it didn't work.

  • Ah, Instead, I'm going to generate a unique I d for his request.

  • Then keep track off the letters request I d here.

  • And when we after we await, Maybe this not let us request I d could have changed.

  • So we compare if the request I d.

  • We're holding onto doesn't correspond to the letters request will just discard the result.

  • And let's see, Okay, now it works on dhe because we only care about the results off the lettuce request.

  • Other other response got discarded.

  • But here now I am searching really slowly and you can see that, uh, until I finish typing.

  • I get no feedback whatsoever from the search boss on DDE That makes me feel that the search boss is a bit unrest conceived.

  • Ah, because you know, before Derbysoft could alive, I type another letter.

  • So it discarded.

  • Do we thought that, uh, the interim rethought?

  • But if we compare that to Coco even on a very slow Internet, I still get the result as I type when?

  • If it lacks behind by several characters.

  • So it's clear that they are not totally this regarding the result that it's not the lettuce.

  • Ah, so I think we can do better.

  • So instead of discarding dirty thought, that doesn't correspond to the lattice request.

  • What if we only discard the result that arrived out off order so we can do this and let's see, Okay, now it seems to work, and you can see here that I get dirty thought I want even before I finished typing.

  • So yeah, you can see that this humble little such boss, it took me three attempts until I can get it right.

  • And that brings me to the first takeaway for this first story, which is to always remember about the potential rest conditions whenever that's a wait call.

  • So each time you see Anna, wait.

  • Maybe think about what else could happen while we're waiting for the result and also think about whether or not it makes sense to use the result after the weight.

  • All right, that's the first story.

  • Ah, we're going to continue with the second story.

  • And this story came from my experience working at task Well, and it it's a real time collaborative project management up on.

  • That's important.

  • Do you see why?

  • Ah, the story happened when we built the up in its early days, So we're just starting out there.

  • It happened about 2 to 3 years ago, and it has to do with something called optimistic updates.

  • So by simple our app, ELISA combine bought and supports that you dragged a task from one list to the other.

  • You wouldn't expect the task to go into the loading state, right?

  • Ah, well, no.

  • You expect a tough to just snap right into the new list on dhe?

  • That's what optimistic update is.

  • So basic idea is we update the U I first in anticipation that the request will be completed successfully and while we synchronize this change with the sewer in the background.

  • So having this kind of experience, like optimistic updates, it's really important for collaborative applications.

  • But our uses react.

  • And when we used to react, we elect to derive our user interface from the underlying data model.

  • So in this case, it's the reader store.

  • So in order to preserve the you'd uni directional data flow, we update the data modo instead and we're going to let it flow into the u I.

  • And for this example, maybe moving a task is a bit complex operation because it involves both a task and the list.

  • So instead, I'm going to just focus on something simpler such ass, um, renaming a task.

  • So when I hit, enter here is going to trigger and even Handler and it will call a function here renamed Task Wishes our action and following this basic pattern, what we did is okay.

  • We update the data model here, and that's going to cost the data model to flow into the user interface.

  • And like that, then we make the AP I call to synchronize with the back in, and because sometimes Internet connection may not be stable are something we're just going on with the A P I Ah, we use a try cash to display the early message just for good measure and that's it.

  • That's how we implemented basic optimistic updates and for most off our operations in our app, we write code following this basic pattern and you know, this works really well and give us a really great experience.

  • Ah, as long as they never as long as nothing goes wrong.

  • So it was well, in the early days when we're just starting out and our focus waas to figure out how we can make project management to that our customers would like to use.

  • However, as we get more customers, we start getting reports such as, Well, our screens are displaying different things, you know, they become inconsistent.

  • Ah, something.

  • Most areas such as this one.

  • So someone writes a comment.

  • The other person didn't receive it because it never gets sent.

  • But the app, that's it, it was already sent.

  • So you know, work is lost and that's pretty serious.

  • I think we came back to our coat and it became clear that our implementation off optimistic update was indeed too optimistic, so there's no room for anything to go wrong here on when it does.

  • Let's see, for example, if this AP I call fails first.

  • We didn't live with our data model back to the previous state, so each client will go its own way and it will be totally out of think on.

  • We also didn't retry the request, and this is really bad because you know, we tried so hard and put in a lot off effort to like club a great experience that the customer would want to use.

  • And now we're just throwing their data away.

  • And you know, that's not what we want for our users.

  • But, well, that was what we implemented.

  • So at the time, we incorrectly assumed that building a single page Leo, Time collaborative Up and task management abs.

  • You know, it's It's just like crud.

  • APS create rate up their delayed, that's all.

  • That's mostly what it does.

  • So it should be a simple as school multi page application because right, because, you know, that's what we know.

  • That's what we're family or with.

  • And if you like Ruby on Leo's, Yeah, doing a create thing is just a simple as that.

  • So it's supposed to be simple, right?

  • Well, maybe not really.

  • And now here here we are, facing its consequence.

  • So we have to fix it.

  • And that means we have to go back and fix all off these operations that we've implemented so far as well.

  • So how it goes, shift that a loss.

  • It's a serious problem.

  • And first to fish that we need to try to a shiv eventual consistency.

  • That means everyone will eventually see the same thing on the screen, which I call the ground truth without having to like pressing the flesh.

  • And second, we want to play went down the loss as much as we can.

  • So let's first talk about the 1st 1 coming back to this coat recalled the previous part where I say, when the FBI call fair, we didn't reworked the state, right?

  • Maybe that's quite easy to face, right?

  • We just started.

  • We stayed over here, and when that's an error, we just revert and then would work.

  • Ah, would it, um, as we learned from our first story.

  • Ah, you see in a wait.

  • And anything could happen here, especially in a real time up.

  • So five simple someone may successfully update this task.

  • Rob, we're awaiting here.

  • And that means the previous title that we start will no longer become well, it and we cannot use it anymore.

  • So D'Amato s cases we try to solve the more days seem to come up.

  • And what about more complex operations that just like moving a task between list How how much accomplished would our court be if we were to handle all the cases in off these operations, if there's something fundamentally wrong with the way we're writing code.

  • So I took another setback and think about the way we are opposing optimistic updates.

  • And then I realized that if we want to have eventual consistency, we must try to stick with the ground truth.

  • I defined it as the letter state that we receive from the Lord.

  • Let the thing that was acknowledged by the back end can be considered the ground truth.

  • And each time we update the immortal optimistically here we are moving away from that ground truth.

  • And considering that everything else may be going on and happening all around, that will make it hot, harder to ever come back to it.

  • So maybe we should leave that data model alone.

  • And don't update it optimistically.

  • But then how would we implement?

  • Optimistic you?

  • I Then we'll figure something out.

  • What if we had a separate data?

  • Modo representing a list off, depending operations, instead, off optimistically update the data model directly?

  • We just added to the list off pending operations.

  • And when it's done, we just remove it.

  • When we render to you, I we overlay, depending change on top off what's inside the model?

  • Essentially computing a protected, optimistic person off the task on the fly in our components.

  • And that could work because if the operation fails, ah, the data model would be left alone.

  • And did you?

  • I will live with back.

  • But if the operation succeeded, the ground truth will be updated first.

  • Then the operation will be removed from the list.

  • And from the U I perspective, it's nothing changed.

  • So now we have the data motor that allows us to do optimistic up.

  • Dre updates without driving us insane.

  • So now let's consider case where I just created a task here, and the blue bar right there represents the time it takes for the operation to complete.

  • But now, since we have optimistic update, I see the task appear right away, and that means I can also interact with it.

  • So let's say I immediately assigned someone to that task.

  • In this case, this epic call would fail because at this time the task doesn't exist in the back and yet right.

  • Ah, so that will lead to a data loss.

  • And we don't want that.

  • And that means I need to wait until the previous operation complete first before before we can work on their subsequent operation.

  • And that essentially means we have to sequence our operations into an operation.

  • Q.

  • So with the operation Q implemented, the action court now looks like this.

  • So this is now even simpler than the 1st 1 that we came up and we just let the cute do its thing.

  • So now off our right operations can be fixed by making it right to the Q instead off calling the FBI directly.

  • Then we can update the U I to compute the projected state by reading from the Cube.

  • So because the operations are now sequenced and managed by the cue, that means it can also take her off retrying the fair request, and that helps us deal with that.

  • The loss.

  • So ah, we haven't covered all the cases yet on preventing further data loss from here.

  • It's like just a matter off asking a series off.

  • What if questions, For example, What if they use their closest the browser arrived.

  • A Q is still running well, we can try to prevent the use of from quitting the browser.

  • All we can put it, the content off the cue into the client side stories so that it can be really soon.

  • Afterwards.

  • All we can do both right.

  • But our user may be using our up from a mobile, the wife, and it might not be practical to do that.

  • So we decided to also say thank you to the client started and that give us as a bonus, give us a building block that if we want to make our upward offline in the future because, you know, progressive Web apps are becoming more popular this year.

  • Ah, so yeah, that's a good bonus for for persisting too cute to the client's knowledge.

  • But then, are you so maybe running?

  • I was up in Monty Po temps.

  • So before we decide to persist the queue, there was no problem because each tap would have its own cue.

  • But now the curious, persistent.

  • So it become a shot mutable state here.

  • If every tap runs the queue at the same time, bad things going to happen.

  • So that can be only one tap that runs this Q.

  • But which one?

  • So today, with today's Web technology, we have shat Web workers and also so its workers that we have two things.

  • Ah, so maybe we don't need any tapped to run it at all.

  • We can just do it in the workers.

  • But today we also have this, so I guess we cannot use the workers yet.

  • So we have to make it so that any top can work on the Q if and only if no other taps work on it.

  • But since our client site storage can be a synchronous, that might be the case where more than one tap looking at the Q and saw that no one's running to kill and both decide to work on it.

  • So who wins?

  • And you know that can be only one top working on the Q.

  • That's a hot requirement.

  • Otherwise, bad things gonna happen.

  • Ah, so we use a shad.

  • Clients I stories and half each have is right, its own i d to distort ish.

  • And after a row we read, we read it back.

  • So the letters, the letters tapped to write winds and the winning top will periodically report status to their shared stories so that other taps know that.

  • Okay, someone is taken care off the Q and it's still alive.

  • But what if that taps somehow disappeared?

  • Um, maybe it maybe it's the use of close it.

  • Maybe it crashed.

  • Ah, then that we have to set up a time out so that other taps could decide that.

  • Well, the tap that originally worked on it has gone and can take over.

  • I can take a word.

  • D'oh.

  • Work left from the previous time.

  • So But what if the tap that disappeared didn't didn't went away?

  • It just slept and it came back.

  • So we also have to handle the kiss where by the Q has been taken away from the top.

  • That is not dead.

  • So, as you can see, there wants a lot off cases that we have to handle to make our more resilient and to prevent that a loss that brings me to the take away that first, I didn't know that writing as crud abs would have to be this complex.

  • You know, there's a lot off tutorials out there chasing your to, like how to make a real time to do application collaborative using less eye socket I Oh, I've never seen any off them.

  • Want me about this when?

  • So these are the problems.

  • Rephrase when we try to build production quality APS, and that's why I want to give this talk so much.

  • And the next takeaway is knowing your tools can help.

  • So there are higher level primitive that can help you right court.

  • That's free off reg conditions.

  • There are some cloud cloud providers, and if the cage that will take care off these problems to some extent, some open source database are designed to be about to synchronize and work off line.

  • So sometimes, ah, if you can take advantage of them, that's great.

  • You have less problem to solve, but sometimes your circumstance might prevent you from using the tools that you want and That's why, in my opinion, the most important thing, the most important thing here, it's to become aware off the existence off this class off problems.

  • Because when if you don't know, the solutions are, if you don't know the wish to to use, at least you know that you should try to avoid it.

  • So to close this talk, I would consider this talk a success if you go home today and become more careful when you see the key would await in your court based, you don't have to be paranoid.

  • Just maybe, just be aware that during and await anything could happen.

  • I don't know if that's paranoid or not, but but and maybe when you test your app tried double clicking everything instead off single clicking and the next time you see all right there would await.

  • I hope you think about this talk.

Ah, this begin.

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

A2 初級

JavaScript應用中的競賽條件,由泰國Pangsakulyanont撰寫|JSConf.Asia 2019。 (Race Conditions in JavaScript Apps by Thai Pangsakulyanont | JSConf.Asia 2019)

  • 2 0
    林宜悉 發佈於 2021 年 01 月 14 日
影片單字