Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
154709 stories
·
33 followers

2.8.10

1 Share

CLI: Stats command - fix incorrect CPU % reporting (#40627)

Read the whole story
alvinashcraft
12 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Introducing Work IQ in the IQ Series

1 Share
From: Microsoft Developer
Duration: 0:36
Views: 44

🎬 Episode 1 premieres on June 2 at 12 PM PT
🔗 Learn more: https://aka.ms/iq-series

Welcome to the Work IQ track within The IQ Series. In the Work IQ episodes, we explore how Work IQ powers AI agents by understanding organizational data, context, and work patterns.

The IQ Series is a developer‑focused learning series exploring Microsoft IQ as the intelligence layer for modern AI systems.

Work IQ is a workplace intelligence layer that delivers a semantic understanding of everything happening across your business. Built on four core components—Chat, Context, Tools, and Workspaces—it continuously transforms signals from across Microsoft 365 and business systems into agent‑ready intelligence, enabling work grounding, reasoning, and permission awareness. The result is a platform purpose-built for agentic use, delivering higher intelligence, speed, efficiency, enterprise scale, and security and governance by design.

Read the whole story
alvinashcraft
12 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Blog: gRPC-Rust Client API Evolution (pt. 1/2)

1 Share

PART 1

The following is a detailed explanation of the background behind the new gRPC-Rust client API. It covers the process I went through while designing it, alternatives considered, trade-offs, and advantages of the final design. If you are only interested in the result itself, please feel free to skip straight to our documentation instead.

Background: gRPC, Tonic, and Tower

gRPC is a high performance Remote Procedure Call (RPC) framework. If you aren’t already familiar with gRPC, please see our introduction.

Tonic is an implementation of the gRPC protocol for the Rust programming language. It is widely used and very popular, with over 12k stars on github. Tonic is designed to be part of the Tower ecosystem, which is a framework that attempts to unify all networking client and service APIs, allowing easy introduction of common middleware for your application.

The gRPC-Rust project was started as an effort to bring all the advanced gRPC features missing from Tonic to the Rust community, like integrated health checking and retries, as well as performance-boosting strategies like zero-copy and arena optimizations.

Obvious Starting Point: Keep the Tonic API?

Tonic is already used by a large number of Rust users, so my initial thought was that it would be great if we could re-use its API. Here’s a quick sample of the current Tonic client-side API:

// Simple unary call (one request, one response):
let response = client
 .get_feature(Request::new(Point { latitude: 409146138, longitude: -746188906,}))
 .await?;

// Bidirectional streaming (many requests and responses in parallel:
let outbound = async_stream::stream! { /* request stream generator */ };
let response = client.route_chat(Request::new(outbound)).await?;
let mut inbound = response.into_inner();

while let Some(note) = inbound.message().await? { /* process responses */ }

When analyzing this more closely, I discovered several issues and limitations:

  • Abstraction Leak: Tonic exposes lower-level HTTP/2 primitives (e.g. GrpcService::ResponseBody is http_body::Body). gRPC applications should not assume that gRPC is using HTTP/2 as a transport to enable the use of other transports (e.g. QUIC) in the future.
  • Unstable Dependency: Tonic builds on Stream from futures_stream (via tokio_stream). These crates are unstable, and we want to be able to have a stable release of gRPC-Rust before they are stabilized.
  • Performance Limitation: Tonic accepts and returns owned protobuf messages. This means the Tonic library handles allocations, which prevents the application from using advanced allocation strategies like arenas. Arenas are important for performance in heavily loaded, highly concurrent RPC systems.
  • Security Concern: Tonic makes it easy (using the ? operator) to propagate outgoing client call statuses to server responses, including metadata, which could contain secrets like tokens or other private information.

What About Tower?

So we’ll need to change the Tonic API, but should we keep using Tower?

In our other supported languages, gRPC directly includes many of the features that you would get from Tower middleware, e.g. timeouts and retries. And, gRPC provides versions of this functionality specifically designed to work well with gRPC. In addition, Tower was not created with streaming in mind, even though it technically works. To implement a bidirectional stream, the Request and Response become asynchronous objects, and the call method returns early in the RPC’s lifecycle to allow the application and library to interact with them.

To illustrate these problems, let’s look at timeouts as an example. The Tower crate provides a timeout module to provide this functionality. The approach is to race the Service it wraps with a timer future, dropping one when the other completes. This works fine for many Service implementations, but it does have some surprising behavior many people are unaware of:

  1. The timeout is not applied while waiting for flow control in poll_ready, meaning your call could block indefinitely.
  2. The timeout only applies to the portion of the call spent waiting for the Response object to be returned from the call method -- which, for streaming RPCs, will be almost immediately. In gRPC, timeouts apply to the total time of the RPC from the moment the client starts attempting the call to the receipt of the final status from the server.

In addition to those behaviors which affect any Service, there is another incompatibility with gRPC: we write the timeout on the wire so that the server is aware of the client’s deadline. If an application was using the timeout module, the gRPC library would never be aware of the timeout in order to propagate it.

Another limitation of Tower is that it makes it hard for the application to control memory allocations: the Response would need to be a complex type that allows you to call into it to receive the message into a buffer. For streaming RPCs, something like this would be needed anyway, but for unary RPCs, which is where arenas are most important, it would be awkward.

Use Tower’s “Style”?

If Tower is a poor fit, should we still keep the same style for calls that Tower and Tonic users are familiar with? I.e.

async fn call(Request) -> Response

We ultimately decided against this approach. With this style, applications that wished to do interleaved operations (“send a message, receive a message, send a message, …”) would need to deal with the two Request and Response streams executing concurrently and implement their own synchronization between the two streams.

Two APIs: Channel vs. Generated Stubs

gRPC actually provides two different APIs: one that the application typically interacts with via the protobuf generated code, and one that the channel (the main client entry point) itself implements, and that interceptors (AKA middleware) would use. The generated API focuses more on usability while the channel API is a lower-level, more powerful, streaming-only design.

In Tonic, this split exists as well, but the proto generated code is just a specialization of the Tonic API using type generics. But this approach is not a requirement, and in fact, there are reasons to avoid it.

With gRPC-Rust, we are taking the opportunity to incorporate some lessons learned from our experience implementing gRPC in many other languages. One such idea we’d like to incorporate is to hide the details of gRPC itself from the generated API, and only expose protobuf messages and necessary primitives. As an example:

// *Not* something like this:
async fn call(ctx: grpc::Context, req: MyRequestMessage, options: grpc::CallOptions)
 -> grpc::Response<MyResponseMessage>;

// More like this instead:
async fn call(req: MyRequestMessage) -> Result<MyResponseMessage, Status>;

// Example usage:
let response = client.call(request).await.expect("RPC should succeed!");

This is similar to gRPC-Java’s design, and it allows applications to focus on the business logic of the application: requests and responses. For other functionality that gRPC provides -- like accessing metadata, disabling retry, reading peer details, etc -- these are generally things that interceptors should be used for, instead.

Generated API

With that in mind, let’s dive into the generated (protobuf) API in isolation first, and understand why the nice, simple API in the example above isn’t good enough. (Then I’ll explain how we ultimately achieved exactly that anyway!)

Arenas

As mentioned earlier, arenas are important for making highly efficient RPC systems that can handle extremely high QPS (Queries Per Second), by grouping related memory operations temporally and spatially. To allow the application to control allocations instead of the library, we were looking for a unary API something like:

// Definition:
async fn call(req: &MyRequestMessageView, resp: &mut MyResponseMessageView) -> Status;

// Usage (with a hypothetical arena API):
let req = MyRequestMessage::new_on_arena(arena).set_id(3);
let res = MyResponseMessage::new_on_arena(arena);
client.call(&req, &mut res).expect("RPC should succeed!");
// res now contains the RPC's response

Can we Make it More Usable?

That API is straightforward, but we understand that many users would not want to pre-declare the response message type manually before making every RPC. We can accommodate both use cases by using the async builder pattern. An async builder is able to return owned messages via an IntoFuture implementation, while also providing an alternative method to perform the call using a pre-allocated response.

We can also improve the ergonomics of the request message parameter. Instead of requiring a reference, we can accept an AsView protobuf type that allows either an owned message or a view to be passed into the call. This is the final API we have implemented:

// Definition:
async fn call<Req>(req: Req) -> UnaryFutureBuilder<..>
where
 Req: AsView<Proxied=MyRequestMsg>;

// Implements the simple usage:
impl IntoFuture for UnaryFutureBuilder {
 type Output = Result<MyResponseMessage, StatusError>;
}

// Implements the advanced usage method:
impl UnaryFutureBuilder {
 async fn with_response_message<Res>(self, res: &mut Res) -> Status
 where
 Res: AsMut<MutProxied = MyResponseMessage>;
}

// Usage:
fn main() {
 let request = proto!(MyRequestMessage{ id: 3 });

 // Simple Usage -- exactly what we wanted originally!:
 let response = client.call(request).await.expect("RPC should succeed!");

 // Arena usage (again with a hypothetical arena API):
 let req = MyRequestMessage::new_on_arena(arena).set_id(3);
 let res = MyResponseMessage::new_on_arena(arena);
 client.call(&req).with_response_message(&mut res).await.expect("RPC should succeed!");
}

We adapted these same concepts to our streaming APIs as well. Below is an example of the bidirectional streaming API:

// Definition:
async fn begin_stream() -> BidiCallBuilder<..>

// Implements the same async builder pattern:
impl IntoFuture for BidiCallBuilder<..> {
 type Output = (GrpcStreamingRequest, GrpcStreamingResponse);
}

// Usage:
fn main() {
 // Simple Usage:
 let (request_stream, response_stream) = client.begin_stream().await;

 request_stream.send(proto!(MyRequestMessage{..}));
 let response = response_stream.recv().await.expect("RPC should succeed!");

 // Arena usage:
 let res = MyResponseMessage::new_on_arena(arena);
 let response = response_stream.recv_into(&mut res).await.expect("RPC should succeed!");
}

Please see the full documentation for more detailed usage examples.

Next Time

This covers the generated code API design process. In Part 2 I’ll go into further details on the channel APIs.

Read the whole story
alvinashcraft
12 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Ember 7.0 Released

1 Share

The Ember project is excited to announce the release of Ember v7.0. Following Ember's Major Version Policy, the major includes only the removal of features that were deprecated until 7.0 as well as other bugfixes. This release of Ember.js means the previous version, 6.12, is now an LTS (Long Term Support) version.

When it comes to introducing new features, Ember generally aims to ship new features in minor releases, offering backwards compatibility for existing code at the same time as giving developers the chance to try out new capabilities. This approach reduces the challenges that teams face for major upgrades, compared to producing big, breaking, splashy major versions with lots of new features.

Looking back at improvements in the 6.x series

In Ember 6.x minor releases, we landed many notable features:

  • In Ember 6.1 we began publishing ember-source as a v2 addon, which enabled Embroider to consume ember-source directly.
  • In Ember 6.3 we added support for template-tag components as route templates per RFC #1046.
  • In Ember 6.8 we landed a new app blueprint with Embroider and Vite-based build system as the default.
  • Also in Ember 6.8 we moved to strict-mode (aka template-tag) component authoring format as the default.
  • Also in Ember 6.8 we added the renderComponent API that allows rendering individual components without a full project.
  • Also in Ember 6.8 we built in tracked versions of JavaScript's native collection types: trackedArray, trackedObject, trackedMap, trackedSet, trackedWeakMap, and trackedWeakSet.

Ember v6.8 was the biggest change to how an Ember project is built in recent memory. The Ember Core Teams have been working on the Embroider+Vite build system and the strict-mode-templates (a.k.a template-tag) for literal years, and this is the first version that we made them the default experience for newly generated Ember apps. Early adopters have been opting into these features for quite some time, but generating an app with Ember v6.8 (or newer) now gives you an incredibly modern developer experience 🎉

Along with these features, countless bugfixes, deprecations that cleared the way for future improvements, RFCs setting the stage for new features, in 6.x the community also:

  • Merged the glimmer-vm monorepo into ember.js to faciliate faster iteration on the rendering engine and the integration with ember.js.
  • Merged the router.js repo into the ember.js repo to prepare for experimentation with a new router architecture and the implementation of the Route Manager RFC
  • Updated our packages to publish via OIDC.
  • Updated broccoli and other dependencies in an ongoing effort to reduce the number of security vulnerabilities. Current vulnerability warnings are only a concern in development mode and should not be exploitable but are annoying.
  • Strived to reduce the number of deprecation warnings when generating a new Ember App. This is an ongoing task.
  • The v2 of Glint was released. This enabled us to make the template-tag component authoring format the default.
  • Created the template tag codemod to help migration to the new authoring format.
  • Created the Vite codemod to help migration to the new build system.
  • Created a legacy Classic Blueprint (@ember-tooling/classic-build-app-blueprint) and supported it in ember-cli-update so that projects can update without moving to the new build system, if necessary.

Thank you to all the contributors that helped make this major-version cycle possible!

How to upgrade to Ember 7.0

The most common approach for upgrading to 7.0 is to upgrade your app to the last version of Ember 6, which is 6.12, resolve all deprecation warnings, and then upgrade to 7.0. If your app or addon runs with no deprecations in the latest release of 6.12, you should be able to upgrade to Ember 7 with no additional changes. Step-by-step directions are below.

If your app is at a much earlier version in the 6.x series, we recommend upgrading in steps across the LTS versions: 6.4, 6.8, and then 6.12.

Follow these steps in order:

  1. Consider upgrading addons used in your app to the latest version that you can. This will reduce the uses of deprecated APIs in your dependencies.

  2. Upgrade your project to the latest patch version of Ember 6.12. Many projects can do this by running npx ember-cli-update --to 6.12.

    When upgrading across the 6.8 boundary, due to changes in the build system, you need to adjust the configuration for ember-cli.

  3. Make sure your app builds successfully.

  4. Resolve all deprecation warnings. These Deprecated APIs are removed in Ember 7.0. You may need to upgrade some of your addon dependencies if they are using deprecated APIs. See the Ember Deprecation Guide for more details about specific deprecations and how to resolve them. Applications that need to upgrade through several versions may want to consider isolating individual deprecations by using ember-cli-deprecation-workflow.

  5. Make sure your app builds successfully and your test suite passes with no deprecations.

  6. Upgrade your app to Ember 7.0. Again, many developers can do this by running npx ember-cli-update --to 7.0.

For help or advice along the way, visit Ember's forums or chat groups.

Ember.js 7.0

Ember.js 7.0 introduces no new public API. Instead, it comprises bug fixes and the breakage of previously deprecated public API from the 6.x cycle.

Deprecations

Ember.js 7.0 introduced no new deprecations. It removed all deprecations that were introduced before 6.10 and slated for removal in 7.0.

Ember 7.0 removes the following features deprecated during 6.x:

  • Removes import Ember from 'ember'. See the RFC or deprecations in your project for a guide on replacement APIs.
  • Removes the publication of AMD bundles by ember-source. This can be opted-into before 7.0 by using an optional feature: see the deprecation guide for more details. This also requires certain dependency updates.
  • Removes importing inject from @ember/service. It is now import { service } from '@ember/service'.

For more details on how to resolve these deprecations in your app, see the deprecations guide.

Bug Fixes

Ember.js 7.0 includes many bug fixes, the following are some of the more notable ones:

  • #21076 Support default globals for strict mode with the runtime template compiler per RFC #1070.
  • #21098 Add support for this in explicit scope for the runtime template compiler.
  • #21107 Fix LinkTo inside inline SVG reloads your application
  • #21109 Fix missing value attribute on radio/checkbox inputs bound to empty string
  • #21122 Fix tracked collections delete() returning true for non-existent entries
  • #21124 Fix {{#each}} runtime crash when array contains null/undefined items with key
  • #21125 Fix crash when accessing negative index of helper positional args
  • #21128 Fix trackedMap and trackedWeakMap reactivity for existing keys
  • #21139 Port BrandedArray fix for Array-as-parent bug in destroyables
  • #21168 Fix EmberArray.reduce to match native behavior
  • #21189 Clear stale metadata references after destruction to allow GC
  • #21202 Fix <LinkTo>'s @current-when argument with nested routes containing dynamic segments

Ember CLI v7.0

Ember CLI 7.0 introduces no new public API, adds no new deprecations, and adds no new bugfixes. This release only adds an automatic breakage to previously deprecated public API from the 6.x cycle. This code will be cleaned up in future releases. You can read more about the deprecations in the deprecation guide

Thank You!

As a community-driven open-source project with an ambitious scope, each of these releases serves as a reminder that the Ember project would not have been possible without your continued support. We are extremely grateful to our contributors for their efforts.

Read the whole story
alvinashcraft
12 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Blog: gRPC-Rust Preview Release

1 Share

Today, the gRPC project is excited to share its first preview release of gRPC-Rust. It can be found at crates.io/crates/grpc. Documentation is available on our website, grpc.io. This release is not recommended for production use at this time, but is being released at an early stage to provide Rust programmers with an opportunity to experiment with the APIs and ensure they will be acceptable for their needs.

What is included

This release includes:

  • gRPC Client APIs. Includes all RPC types including unary and streaming.

    • gRPC Server support is coming soon.
  • Protobuf support using Google’s Protobuf-Rust library and tools.

    • Messages are generated from Protobuf-Rust via protoc.
    • gRPC generated RPC code using our protoc plugin.
  • Low-level RPC API for creating interceptors and performing RPCs without the need for the protobuf generated code.

  • Support for the Tokio async runtime.

    • Future gRPC-Rust releases intend to work with any runtime; however, for this preview we are only targetting Tokio.

Learn more

Documentation for this gRPC-Rust preview can be found on grpc.io. The following resources are available:

Contact the team

Please reach out to the team if you have any feedback or encounter any issues:

Join us at gRPConf 2026!

If you’re interested in meeting the gRPC team, discussing related topics with others in the industry, or maybe even sharing your own experiences or advice in a talk, please mark your calendar for Thursday, September 3rd, when we’ll be holding this year’s gRPC developer’s conference at the Computer History Museum in Mountain View, CA.

Read the whole story
alvinashcraft
12 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Microsoft teases new Surface hardware and ‘a new era of PC’

1 Share
A photo of Microsoft’s 2024 Surface Laptop.

I pondered the other day what's next for Microsoft's Surface PC lineup, and it looks like we're about to find out. Windows and Surface chief Pavan Davuluri has just teased "something new is coming for developers," complete with a mysterious image of what looks like a curved display edge.

Davuluri notes that whatever is coming is "not a new OS version," so that rules out the potential for Windows 12 to be announced at Microsoft's Build developer conference next week. Separately, the Windows account on X posted a similar cryptic tweet, promising "a new era of PC" with coordinates pointing to where Computex is hosted in Taipei.

Read the full story at The Verge.

Read the whole story
alvinashcraft
13 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories