That Conference 2018 – Correcting Common Mistakes When Using async/await in .NET

That Conference 2018, Kalahari Resort, Lake Delton, WI
Correcting Common Mistakes When Using async/await in .NET – Brandon Minnick

Day 1, 6 Aug 2018  4:00 PM

Disclaimer: This post contains my own thoughts and notes based on attending That Conference 2018 presentations. Some content maps directly to what was originally presented. Other content is paraphrased or represents my own thoughts and opinions and should not be construed as reflecting the opinion of the speakers.

Brandon Minnick

Developer Advocate, Microsoft

@TheCodeTraveler

https://www.codetraveler.io/THAT-2018-AsyncAwait/

Executive Summary

  • Helps to know underlying IL that’s generated
  • Helps to know core task-based objects that async/await use
  • ConfigureAwait(false) if you don’t need to come back to UI thread
  • .GetAwaiter().GetResult() instead of await to get synchronous execution

Multi Threading

  • e.g. ReadDataFromUrl
    • Our method is async
    • does await on DownloadDataTaskAsync
    • 1st chunk of code is run by the thread that calls this method
    • 2nd thread–calls the Download method
    • After await, execution picks up with 1st thread
  • Typically, first thread, i.e. main thread, is the UI thread
  • UI thread
    • Draws UI on screen
    • Rule-of-thumb for executing on UI thread. Because refresh rate is 60Hz, don’t take more then 1/60 sec (17 ms)

Intermediate Language

  • Compiler generates class for your original method
  • Implements IAsyncStateMachine
  • Every local variable from method becomes private field in class
  • MoveNext method
    • Giant switch statement
    • $PC keeping track of state
    • Also a big try/catch block surrounding everything

Quick Review

  • async keyword adds 100 bytes
  • Every async method becomes a class

Await Every Async Method

  • Non-awaited async methods hide exceptions
  • Ditto for Task.Run — GetAwaiter().GetResult() will ensure we catch exception

Let’s Fix Some Code

  • Can’t await in a constructor
    • ICommand–made for fire and foreget
    • In Execute method, do async lambda with await
    • So from constructor, we can call MyCommand.Execute(null)
  • Never use async void ?
    • Not entirely true
    • Don’t use async void when not on UI thread
    • But on UI thread, if you throw exception from within async void–you’ll catch the exception
  • So from constructor, call Initialize(), which is an async void and can do the await
  • NEVER use .Wait
    • Blocks calling thread entirely
    • Doesn’t unwrap an exception
  • NEVER use .Result
  • Way better method
    • GetAwaiter().GetResult()
    • Does unwrap any exceptions
    • Can get the result from the async method
  • Note: .GetAwaiter().GetResult() is to be used in non-async method
    • In async method, just use await keyword
  • ConfigureAwait(false)
    • By default, you context switch back to UI thread
    • But this is expensive–background thread has to wait for UI thread
    • Context switch takes time
    • When background thread is done, execution stays on that background thread. Does not come back to UI thread
    • But note that you do need to come basck to UI thread if that method does some stuff with the UI, e.g. modify a control
  • ConfigureAwait(true)
    • This is the default, equivalent to not having ConfigureAwait() there at all
  • Don’t call .Result
    • Replace with await that method call to get the result directly
  • Special case, returning await something that returns Task<>
    • You can return the task directly, rather than awaiting it, then doing async on the method
    • Look for “return await”
  • Exception to this rule
    • You should await if you want to catch exception in method that you’re calling
    • So you could argue not to every do that trick

Async/Await Best Practices

  • Never use .Wait or .Result
    • Use await keyword
    • Or .GetAwaiter().GetResult()
  • Fire and forget tasks
    • Use ICommand
    • (or) async void (if you know you’re going to be on main thread)
  • Avoid return await
    • Remove async keyword
    • Except in try/catch blocks or using blocks
  • Utilize ConfigureAwait(false) as much as possible
    • In methods that don’t touch the UI

Xamarin University

  • Various course, e.g. CSC350: Using async await

Advertisements

That Conference 2018 – API Design Isn’t Just Nouns and Verbs

That Conference 2018, Kalahari Resort, Lake Delton, WI
API Design Isn’t Just Nouns and Verbs – Keith Casey

Day 1, 6 Aug 2018  2:30 PM

Disclaimer: This post contains my own thoughts and notes based on attending That Conference 2018 presentations. Some content maps directly to what was originally presented. Other content is paraphrased or represents my own thoughts and opinions and should not be construed as reflecting the opinion of the speakers.

Keith Casey

  • Okta – SSI identity management on the web
  • OAuth as a service, for Fortune 10 companies
  • “A Practical Approach to API Design” – Casey


Assumptions

  • Nothing/nobody is perfect
    • Will be attacks against API, some intentional, some not


What Is an API

  • contract about how two pieces of software interact
    • Can have lots of ceremony (e.g. SOAP) or less (e.g. REST)
    • REST is not a protocol, but a pattern for interacting with things
  • How one piece of software talks to another


Application Programming Interface

  • It’s an interface
  • We have users of our API
  • “Don’t Make Me Think” – Krug
    • Can apply same principles to API, just like GUI
  • Stop and think about how API appears to its users


What are we doing now?

  • Frameworks for creating RESTful services–there are tons
  • We generally default to some framework for building an API
  • Typically it just maps tables in database to verbs–CRUD over HTTP
    • But we normally don’t want to expose row-based pattern as the API


What is Bootstrap?

  • Clean, simple UI
  • Standard, consistent, reusable components
  • The bane of every UX designer


Why ?

  • Bootstrap treats every application the same
    • Ignores the application, what they use it for, how they use it


GraphQL

  • Expose additional data from database via API
  • “GraphQL is the CSV of API Design”
    • Ignores requirements, just give them every field and user can choose
  • Same thing, treats every application the same


What Should We Do Better?

  • E.g. Anonymous visitor to web site, want to create user account
    • ..so that I can see my account balance
  • Must ask why on user story in order to understand the requirement
    • Can then build the right thing, better, faster
  • The things that we build need to be valuable to users
  • Developers want to
    • Build something useful
    • Go home


Think About the Story

  • What are the choices available to a user at any given time


Steps in Designing API

  • Identify who uses API
  • Identify high-level activities
  • Break down into steps
  • Create API Definitions
    • Prior to this step, it was a business process
  • Validate API


Identify Participants

  • List consumers of the API (directly or indirectly)
    • e.g. internal or external
  • Capture a bit about them–location, description


Identify High-Level Activities

  • Activity–work that produces a desired income, accomplished by one or more participants
    • Must understand user’s goals at this point
  • Activity might have multiple steps
  • Make note of description, participants


Break Down into Steps

  • Each step is accomplished by single participant
  • Step may have stages executed by different participants, but each step maps to single participant
    • Watch out for “and” steps–could be multiple steps


Create API Definition

  • Identify resources (the nouns)
  • May start to find dependent/nested resources
    • And business rules around the relationships
  • If API user needs to understand database schema in order to use API
    • You’re doing it wrong


Resource Relationship

  • e.g. Movie, Actor, Character relationship


Validate Your API

  • Ensure that your API will meet the requirements of the users
  • Walk through each use case
    • Individual steps in use case on notecards
  • You document how many activities need each API action
    • Helpful to know how widely used each endpoint is
    • Correction–each activity has steps, each step on a notecard; document which activities each step needs to be a part of


Validation Options

  • Compare API capabilities against UI wireframes
  • Build simple mock interfaces in a micro-framework
  • Write example code showing how to use it
    • Mock API, Happy JS?
  • Write end user documentation


What Should We Avoid?

  • Don’t assume we know all the use cases
    • e.g. multi-tool that has everything


Don’t collect or share extra data

  • Combridge Analytica
  • Why should people share this information?
  • How might a bad actor use this information?


Don’t Leak Your Own Data

  • E.g. giving user an incremented customer ID
  • What can someone tell by using your API?


Don’t Roll Your Own Encryption

  • Use an existing library
  • No, no, no don’t do your own encryption

That Conference 2018 – Know What Your Code Is Doing to SQL Server

hat Conference 2018, Kalahari Resort, Lake Delton, WI
Know What Your Code Is Doing to SQL Server – Kevin Boles

Day 1, 6 Aug 2018

Disclaimer: This post contains my own thoughts and notes based on attending That Conference 2018 presentations. Some content maps directly to what was originally presented. Other content is paraphrased or represents my own thoughts and opinions and should not be construed as reflecting the opinion of the speakers.

Kevin Boles
TheSQLGuru@gmail.com

Executive Summary

  • Handful of specific examples of ways that you can end up with poorly performing SQL Server queries
  • Improper use of Entity Framework sometimes to blame
  • Always pay attention to exact T-SQL that is being used

 

Miscellaneous

  • Recommend 192GB on server, go beyond max memory (128GB)
  • In memory OLTP now down in standard edition
  • SQL Server 2016–It Just Runs Faster
    • Good blog posts on performance improvements
  • Get on 2016 or 2017

 

Entity Framework is tool that simplifies, but lower performance

  • Can be very productive
  • Several traps, easy to fall into
  • Other ORMs have similar problem

 

Being too greedy with rows

  • EF exposes objects without knowing values
  • E.g. pull data out to list, when do Where clause on the list
    • Pulls entire table before filtering
  • Do filtering on SQL Server
    • Provided that you ave the proper filter
  • Or could bring back to IQueryable

 

N+1 Select Problem–minimize trips to DB

  • ANTS performance profiler
  • E.g. One query to parent entities, 2nd query for each child to get related entities
  • Round-trip for each child query
  • Lazy Loading
  • “N+1 select problem”
  • If you know you want child data ahead of time, do the original query to include it
  • Use Eager Loading
    • .Where, .Include
  • Make sure that you really need them
  • Don’t do aggregation in client–do it in SQL Server
  • E.g. if we’re just counting child objects, do it with aggregate function in SQL Server
  • Don’t iterate and don’t get data that you don’t need

 

Being too Greedy with Columns

  • E.g. pull all Pupils from school, then iterate to dump out certain stuff
  • Selecting all columns when you just need subset of columns
  • EF doesn’t know what columns you want
  • Causes two problems
    • More data than we need
    • Impossible to index, since we pull everything back
  • SELECT WITH NO LOCK
    • If acceptable, can be faster because you don’t wait for confurrent transactions
  • If you’re pulling all columns, you’re locking entire table for the length of that query
  • Select new to just get you want

 

Mismatched Data Types

  • If data types don’t match, even simple queries can perform poorly
  • E.g. search for entities with particular zip code
  • Dev system should match prodution system in terms of scale
  • Find query runs fast, EF runs very slowly
  • Query plan warning
    • CONVERT_IMPLICIT
    • Function on a column in a WHERE clause
  • Column in database is VARCHART, but .NET has string, which is UTF16 Unicode
  • SQL Server does
    • INDEX SCAN of every zip code
    • Big I/O cost
    • Then converts the data–CPU hit
    • Optimizer can’t do prediction because  data is different than what’s in the index
  • Solution
    • Edit model to tell EF to use VARCHAR, using column annotation
    • In code, attribute
  • Do not let EF create models, code-first

 

ORM ?

  • He recommends not using one

 

ADO.NET

  • 3 things to remember about stuff on internet about SQL Server
    • Who wrote it
    • When was it written
    • Does it apply to my system
  • ADO.NET Parameterized Queries
  • AddWithValue–get rid of this

 

Overly Generic Queries

  • Allowing searching on multiple fields
  • So we construct one query, where clauses for each search field
  • == null or matches
  • IS NULL OR stuff gets into query
  • Bad because it builds query plan just once for all the possible search combinations
  • Always runs same query plan, no matter what you search on
  • Can’t do a seek on index
  • Options
    • Stored procedure — Gail – “catch all queries”
    • Conditionals in EF side, exclude clauses
    • Make SQL Server recompile plans each time–from within EF. Sometimes good
    • Could write interceptor, option(recomiple)

 

Bloating the plan cache

  • Reuse of execution plans often a good thing, avoid regenerating plan
  • In order for a plan to be reused, the statement text must be textually identical, wihch as we just saw, is case for parameterized queries
    • Ad-hoc workloads

 

Skip / Take

  • OFFSET FETCH
  • Next time we run query, we get different query plan
  • Enable SQL Server setting ‘optimize for ad-hoc workloads ‘
    • Less aggressive at caching plans, generally a good thing
  • EF6, pass in lambdas
    • In SQL, values are paremetrized, so we don’t recreate cache plan

 

Inserting data

  • EF will run separate INSERT statements for every row being added
  • Not good if you have to insert a lot of data
  • Can use EF.BulkInsert or use EF 7 (has this out-of-the-box)

 

Code First, Performance Last

  • Never allow your code to create your storage constructs
  • (He means–code-first used to refresh database object)

 

Other Potential Issues

  • Improper use of IN clauses
    • >16 clauses in IN clause if bad
  • Correlated subqueries instead of JOINs
  • Parameterized queries with parameters defined to be length of data they contain
  • Chatty apps
  • Security conerns
  • Increased IO and app bloat due to asking for too mcuh data

 

That Conference 2018 – Finding Your Way to a Microservices Architecture

That Conference 2018, Kalahari Resort, Lake Delton, WI
Finding Your Way to a Microservices Architecture – Dana Hart

Day 1, 6 Aug 2018

Disclaimer: This post contains my own thoughts and notes based on attending That Conference 2018 presentations. Some content maps directly to what was originally presented. Other content is paraphrased or represents my own thoughts and opinions and should not be construed as reflecting the opinion of the speakers.

Dana Hart
Northwestern Mutual
@dmhart13

Executive Summary

  • Lots of good reasons for re-factoring monolithic application as microservices
  • Architecture has multiple micro SPAs talking to multiple microservices

 

Monolithic application

  • Browser
    • UI / Business Loic / User Logic
    • Databases
  • One application on single platform
  • Drawbacks
    • Maintenance
    • Hard to test
    • Longer deploys
    • Longer downtimes
    • Doesn’t scale
  • How we got there
    • Probably started out small
    • Features have been added

 

Scaling the mono

  • Development–multiple teams in one repo
  • Continuous Deployment – updates = outages, higher risk
  • Increased Transactions – ru nmore copies of application?  Scale out metal?
  • Is this good enough? Working?

 

Frustration is an important part of success

 

Software microarchitecture

  • Set of patterns used together to realize parts of a system
  • Building block for piecing together cohesive portions of an overall architecture

 

Microservices

  • Structure application as collection of loosely coupled services
  • Enables continuos delivery and deployment of large, complex applications

 

Diagram

  • UI talks to various microservices
  • Each microservice talking to one database

 

Reasons to convert

  • Decomposes complexity
  • Developed independently
  • Deployed independently
  • Scaled independently
  • Smaller deploys
  • More frequent deploys
  • Lower deployment risk

 

How to start

  • Find piece that can exist independently
  • Don’t just convert, but re-factor

 

REST review–constraints

  • Uniform interface
  • Client-server
  • Stateless
  • Cacheable
  • Layered system
  • Code on Demand

 

Define your subdomain

 

REST review

  • HTTP verbs–GET, POST, PUT, DELETE
  • Sensible resource names
  • XML and JSON
    • Recommend JSON over XML
    • Easier to consume by browser
  • Fine-grained resources
    • Simple resources that you can apply CRUD to
  • Idempotence
    • Get same response every time if inputs are the same
  • Safety

 

Micro SPAs

  • Take original monolithic UI
  • Split into separate pages, each being a SPA
    • /store
    • product
    • /order

 

Deployment Patterns

  • Multi service instances per host
  • Service instance per Host / VM / Container
  • Serverless deployment
  • Service deployment platform
    • Automated infrastructure

 

Move everything to cloud

 

Reverse proxy

  • URL goes thru reverse proxy (external request)
  • Look up services, find target address
  • E.g. use NGINX

 

API Gateway

  • SPA Containers send requests
  • To API Gateway
    • Could implement security
    • Load balancing
  • Farms out to API Containers

 

Micro Application platform–diagram

  • Request
  • Reverse Proxy
  • SPAs
    • Can talk to one or more services
  • API Gateway
  • Services
  • Databases

 

At end

  • Multiple SPAs
  • Multiple services
  • No deployment downtime
    • Pre-production environment
    • Kubernetes handles this

 

Questions

 

Q: When do you decide to create an API that might combine logic from two sub-domains?

A: We wouldn’t combine the services, but let the UI do the model translation between the two services. But sure, you could add a service that aggregates data from multiple services.

 

Q: How do you handle versioning?

A: Many opinions around versioning. We have pattern of “v1”, “v2” in front of API. “No breaking changes” unless it’s a major version chance.

 

Q: How do you decide what goes in what database?

A: We still have one large database. If the entities have relationships, we’d be hesitant to split them out.

 

Q: How do you manage to get common look/feel across the SPAs

A: It’s not easy. We had designers to create common UI Sketch components. Then devs create UI framework around these common elements. Partnership between Engineering and Design.

 

Q: How did you avoid applying legacy change management techniques (monolithic) to new architecture. Had to educate various teams to demonstrate that we’re now running with lower risk. Dev team “owns” the result of a deployment, responsible for it. We use New Relic for monitoring.

 

Q: We have 3rd party integration with a service that is not stateless.

A: Sometimes you do get stuck with a vendor’s implementation. Could give examples to vendor of what work better for you.

 

Q: Where do you pull stuff from multiple services together?

A: We do it in UI layer, model translation, pulling stuff together.