If you require synchronous code you may want to check out TeaVm. It supports full Java thread semantics in the browser.
On Thursday, 1 September 2016, Ian Preston <[email protected]> wrote: > Cool example. You are right. > > We are migrating our code to asynchronous. :-) > > > > On Thursday, 1 September 2016 13:59:45 UTC+1, Thomas Broyer wrote: >> >> Consider the following code: >> >> class Foo { >> String bar; >> >> synchronized String getBar() { >> if (bar == null) { // OK, we all know this is bad in the Java world, >> just bear with me for this sample code >> Future<String> realBar = …; // make a call that returns a >> CompletableFuture<String> >> bar = realBar.get(); >> } >> return bar; >> } >> } >> >> You're proposing that it's somehow translated more or less to: >> >> var _symbol$bar = Symbol("Foo.bar"); >> class Foo { >> async getBar() { // Note: transformed to 'async', no 'synchronized' >> if (this[_symbol$bar] == null) { >> var realBar = …; >> this[_symbol$bar] = await realBar.get(); // transformed to await >> } >> return this[_symbol$bar]; >> } >> } >> >> Now imagine that while await⋅ing realBar.get(), getBar() is called again, >> on the same Foo instance (triggered by an event; for example, getBar() is >> called from a click handler, and the … returning the >> CompletableFuture<String> fetches some resource through HTTP). >> Looking at the original Java code, you'd expect that the second call is >> blocked until the first one terminates and releases the lock on the Foo >> object, so the first call would set the bar field and the second call would >> skip the 'if' branch. >> In JS though, the second call would *enter* the 'if' branch and make a >> second call; then, when each 'realBar' is completed, the private (through >> Symbol) property is set: twice; and if the call that returned a >> CompletableFuture<String> is stateful, that means the state has been >> modified twice. >> What kind of JS would you produce that'd prevent this from happening? >> >> I wouldn't trade "emulating CompletableFuture#get" for "bloated JS and a >> much more complex compiler". The Pareto rule tells us that you should just >> embrace asynchrony and live with only the non-blocking API (CompletionStage >> basically, plus getNow() and a few others). >> >> On Thursday, September 1, 2016 at 11:53:45 AM UTC+2, Ian Preston wrote: >>> >>> Interesting question, Thomas. I believe it should still work. Consider >>> the following: >>> >>> 1. A 'thread' comes into a method and obtains a lock on A. >>> 2. whilst holding the lock, it makes an async call to >>> CompletableFuture.get() >>> 3. Somewhere down the call stack some state which is guarded by the lock >>> on A is modified >>> On the JVM, either that lock is not re-entrant, in which case it is a >>> deadlock, or it is re-entrant and modifying the state is fine. We only have >>> one thread in JS so it is fine. >>> >>> Correct me if I'm wrong, but I believe this means that GWT could >>> continue to ignore synchronization, and get the same results assuming non >>> deadlocking programs, which can't be translated without a full emulator >>> like doppio anyway. >>> >>> >>> On Thursday, 1 September 2016 10:22:08 UTC+1, Thomas Broyer wrote: >>>> >>>> >>>> >>>> On Wednesday, August 31, 2016 at 11:58:51 PM UTC+2, Ian Preston wrote: >>>>> >>>>> One idea, which would be awesome from a user perspective, is the >>>>> following: >>>>> >>>>> Emulate CompletableFuture with native Promises. Then if the >>>>> synchronous cf.get() call is used, then translate that to await, and make >>>>> the function it is in async (in JS land). This would automatically change >>>>> the signature to a CompletableFuture, and then propagate this up to all >>>>> callers. If it makes it all the way to a function exposed with JsInterop, >>>>> then that function changes signature like the rest of them to return a >>>>> promise. The consumer of this function is obviously in JS and so can >>>>> handle >>>>> the promise fine. This would equate to translating the synchronous java >>>>> calls which wait on a CompletableFuture (Promise) to return promises in >>>>> JS. >>>>> This wouldn't require any changes to the Java code - it could continue in >>>>> its synchronous style, and not disrupt JVM based users of the same code. >>>>> >>>> >>>>> Thoughts? >>>>> >>>> >>>> 'await' is not synchronous, which means things can happen while >>>> awaiting, which could mutate state you'd rely on being immutable because >>>> you 'synchronized' it (in other words: how would your proposal work with >>>> the 'synchronized' keyword? GWT currently simply ignores 'synchronized' >>>> because JS is single-threaded anyway; now what if you call >>>> CompletableFuture#get() within a 'synchronized' function, possibly several >>>> levels deep in the call-stack?). >>>> >>>> There are good reasons why only async functions can call async >>>> functions, and only async functions can use the await keyword: explicit vs. >>>> implicit. >>>> >>>> -- > You received this message because you are subscribed to the Google Groups > "GWT Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected] > <javascript:_e(%7B%7D,'cvml','google-web-toolkit%[email protected]');> > . > To post to this group, send email to [email protected] > <javascript:_e(%7B%7D,'cvml','[email protected]');>. > Visit this group at https://groups.google.com/group/google-web-toolkit. > For more options, visit https://groups.google.com/d/optout. > -- Steve Hannah Web Lite Solutions Corp. -- You received this message because you are subscribed to the Google Groups "GWT Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/google-web-toolkit. For more options, visit https://groups.google.com/d/optout.
