Archive for March 17, 2020

Tuesday, March 17, 2020

Understanding Combine

Joseph Heck:

For anyone keeping up with #combine, @mattneub has published Understanding Combine online, first glance looks like a great tutorial with a lot of depth[…]

Previously:

Rewriting Dropbox’s Sync Engine in Rust

Sujay Jayakar:

Rewriting the sync engine was really hard, and we don’t want to blindly celebrate it, because in many environments it would have been a terrible idea. It turned out that this was an excellent idea for Dropbox but only because we were very thoughtful about how we went about this process. In particular, we’re going to share reflections on how to think about a major software rewrite and highlight the key initiatives that made this project a success, like having a very clean data model.

[…]

There were few consistency guarantees, and we’d spend hours debugging issues where something theoretically possible but “extremely unlikely” would show up in production. Changing the foundational nouns of a system is often impossible to do in small pieces, and we quickly ran out of effective incremental improvements.

[…]

Rust has been a force multiplier for our team, and betting on Rust was one of the best decisions we made. More than performance, its ergonomics and focus on correctness has helped us tame sync’s complexity. We can encode complex invariants about our system in the type system and have the compiler check them for us.

[…]

The Control thread is designed to be entirely deterministic when its inputs and scheduling decisions are fixed. We use this property to fuzz it with pseudorandom simulation testing.

[…]

We redesigned the client-server protocol to have strong consistency. The protocol guarantees the server and client have the same view of the remote filesystem before considering a mutation. Shared folders and files have globally unique identifiers, and clients never observe them in transiently duplicated or missing states. Finally, folders and files support O(1) atomic moves independent of their subtree size.

Previously:

Update (2020-03-27): Sujay Jayakar:

  1. we write almost all of our logic on a single thread, using futures to multiplex concurrent operations on a single thread. then, we make sure all of the code on that thread is deterministic with fixed inputs. there’s lots of ways code can sneak in a dependency on a global random number generator or time.

  2. have traits for the interfaces between the control thread and other threads. we also mock out external time behind a trait too.

  3. then, wrap each real component in a mock component that pauses all requests and puts them into a wait queue.

now, instead of just calling .wait on the control thread future, poll it until it blocks (i.e. returns Async::NotReady). this means that the control thread can’t make any progress until some future it’s depending on completes. then, we can look at the wait queues and psuedorandomly unpause some subset of them and then poll the control thread again. we repeat this process until the test completes.

all of these scheduling decisions are made psuedorandomly from a fixed RNG seed that’s determined at the beginning of the test run. we can also use this seed for injecting errors, generating initial conditions, and “agitating” the system by simulating other concurrent events. the best part is that once we find a failure, we’re guaranteed that we can reproduce it given its original seed.

in fact, we actually don’t even log in CI at all. we run millions of seeds every day and then if CI finds a failure, it just prints the seed and we then run it locally to debug.

iOS Apps Snooping on Pasteboard Data

Talal Haj Bakry and Tommy Mysk (via MacRumors):

This article provides an investigation of some popular apps that frequently access the pasteboard without user consent. These apps range from popular games and social networking apps, to news apps of major news organizations. We found that many apps quietly read any text found in the pasteboard every time the app is opened. Text left in the pasteboard could be as simple as a shopping list, or could be something more sensitive: passwords, account numbers, etc.

[…]

The method is simple: Once we connect and pair the devices with Xcode, we can read the system log of the device. Fortunately, all pasteboard events are clearly logged.

[…]

We include any app that requests and reads the content of the system-wide pasteboard every time it’s opened, and consider it to be highly suspicious. There are games and apps that do not provide any UI that deals with text, yet they read the text content of the pasteboard every time they’re opened.

Nick Heer:

Most apps do not breach user trust in this manner, so it is surprising to see the breadth of very popular apps that are doing so in this case — many of which have no practical reason for reading pasteboard data in the first place. It’s the kind of thing that makes me wonder if they are all, perhaps, using a shared development framework or analytics bundle.

One way to resolve this may be to require consent from the user before the app can access the pasteboard. That consent can be provided in the form of the user tapping the paste button, upon which point the app is authorized.

Just because I once pasted something into an app doesn’t mean I want it to have ongoing access to read the pasteboard. Yet I don’t want to be prompted for each and every access, either. This seems like another case where it would be helpful for the system to maintain an audit log of what each app was doing.

Previously:

Microsoft Plots the End of Visual Basic

.NET Team:

We are supporting these application types to provide a good path forward for the existing VB customer who want to migrate their applications to .NET Core. This allows Visual Basic customers to take advantage of new platform features like side-by-side deployment, cross platform support, performance and new API improvements.

One of the major benefits of using Visual Basic is that the language has been stable for a very long time. The significant number of programmers using Visual Basic demonstrates that its stability and descriptive style is valued. Going forward, we do not plan to evolve Visual Basic as a language. This supports language stability and maintains compatibility between the .NET Core and .NET Framework versions of Visual Basic. Future features of .NET Core that require language changes may not be supported in Visual Basic. Due to differences in the platform, there will be some differences between Visual Basic on .NET Framework and .NET Core.

Paul Thurrott (via Hacker News):

When Microsoft released the .NET version of Visual Basic, originally called Visual Basic .NET, alongside C# at the beginning of the .NET era, the two languages were evolved together and had roughly identical feature sets. But this changed over time, with professional developers adopting C# and many fans of classic VB simply giving up on the more complex but powerful .NET versions of the environment. Today, virtually all of Microsoft’s relevant developer documentation is in C# only, with VB source code examples ever harder to find.

[…]

What this means to VB developers is that they might be able to bring their existing codebases forward to .NET Core or, soon, to .NET 5.0, which will replace both the traditional .NET and the open-source and cross-platform .NET Core when it’s released in late 2020. The issue is that not all legacy technologies will be supported going forward, so developers using WebForms, Workflow, or Windows Communication Foundation (WCF) will need to stick with classic .NET. Those applications will continue to work and be supported until the underlying Windows versions are retired; classic .NET support life cycles are tied to the Windows versions on which they were initially deployed.

Previously: