通过HTML5本地存储实现同步原语 [英] Implementation of synchronization primitives over HTML5 local storage

查看:107
本文介绍了通过HTML5本地存储实现同步原语的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一种情况,其中浏览器有两个或多个指向同一来源的选项卡。不同选项卡的不同事件循环可能会在访问本地存储时导致竞争条件,并且不同的选项卡可能会覆盖彼此在本地存储中的更改。



我正在编写一个面临这种竞争条件的Web应用程序,因此我想了解可以在这种情况下使用的不同同步原语。 / p>

解决方案

我读相关的W3C规范,以及评论 这篇关于主题的博客文章表明,所谓发生的事情是,浏览器全局互斥锁控制对每个域的访问 localStorage的。每次检查本地存储时,JavaScript执行的每个单独的线程(参见下面我相当自信的意思)都必须尝试获取存储互斥(如果它还没有它)。一旦它获得互斥锁,它就不会放弃直到它完全完成。



现在,什么是线程,以及一个线程完成意味着什么?唯一有意义的事情(唯一真正符合Hixie声称互斥体使事情完全安全的事情)是线程是某些浏览器上下文中的JavaScript代码事件。 (请注意,一个可能的事件是刚刚加载了< script> 块。)浏览器中JavaScript的性质通常是<$ c中的代码$ c>< script> 阻止或任何类型事件的处理程序中的代码运行直到它停止;也就是说,运行到< script> 主体的末尾,否则运行直到事件处理程序返回。



<那么,考虑到这一点,存储互斥体应该做的是强制所有共享域脚本在尝试声明互斥锁时阻止其号码中的一个已经拥有它。它们会阻塞,直到完成拥有的线程—直到< script> 标记代码耗尽,或直到事件处理程序返回。这种行为将从规范中实现这一保证:


因此,Storage对象的length属性以及各种属性的值该对象在脚本执行时无法更改,除了脚本本身可预测的方式。


但是,它看来基于WebKit的浏览器(Chrome和Safari,也可能是Android浏览器,现在也许是Opera?)不会对互斥体的实现感到烦恼,这会让你陷入困境,迫使你提出这个问题。如果您关注这样的竞争条件(一种非常合理的态度),那么您可以使用博客文章中建议的锁定机制(由曾经或确实为Stackoverflow工作的人)或者实现版本计数系统检测脏写。 (编辑—现在我考虑一下,一个RDBMS风格的版本机制会有问题,因为仍然是检查版本的竞争条件!)


Consider a scenario where a browser has two or more tabs pointing to the same origin. Different event loops of the different tabs can lead to race conditions while accessing local storage and the different tabs can potentially overwrite each other's changes in local storage.

I'm writing a web application that would face such race conditions, and so I wanted to know about the different synchronization primitives that could be employed in such a scenario.

解决方案

My reading of the relevant W3C spec, and the comment from Ian Hickson at the end of this blog post on the topic, suggests that what's supposed to happen is that a browser-global mutex controls access to each domain's localStorage. Each separate "thread" (see below for what I'm fairly confident that means) of JavaScript execution must attempt to acquire the storage mutex (if it doesn't have it already) whenever it examines local storage. Once it gets the mutex, it doesn't give it up until it's completely done.

Now, what's a thread, and what does it mean for a thread to be done? The only thing that makes sense (and the only thing that's really consistent with Hixie's claim that the mutex makes things "completely safe") is that a thread is JavaScript code in some browser context that's been initiated by some event. (Note that one possible event is that a <script> block has just been loaded.) The nature of JavaScript in the browser in general is that code in a <script> block, or code in a handler for any sort of event, runs until it stops; that is, runs to the end of the <script> body, or else runs until the event handler returns.

So, given that, what the storage mutex is supposed to do is to force all shared-domain scripts to block upon attempting to claim the mutex when one of their number already has it. They'll block until the owning thread is done — until the <script> tag code is exhausted, or until the event handler returns. That behavior would achieve this guarantee from the spec:

Thus, the length attribute of a Storage object, and the value of the various properties of that object, cannot change while a script is executing, other than in a way that is predictable by the script itself.

However, it appears that WebKit-based browsers (Chrome and Safari, and probably the Android browser too, and now maybe Opera?) don't bother with the mutex implementation, which leaves you in the situation that drove you to ask the question. If you're concerned with such race conditions (a perfectly reasonable attitude), then you can use either the locking mechanism suggested in the blog post (by someone who does, or did, work for Stackoverflow :) or else implement a version counting system to detect dirty writes. (edit — now that I think about it, an RDBMS-style version mechanism would be problematic, because there'd still be a race condition checking the version!)

这篇关于通过HTML5本地存储实现同步原语的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆