Cloud Tech by Victor

Search

30 results for “async

Search results

Backend

Python Async Programming

How asyncio's single-threaded event loop achieves concurrency without threads, why blocking calls silently defeat it, and when async actually helps versus when it's pure overhead.

Database Replication

A PostgreSQL primary crashes right after committing a transaction, under asynchronous replication. Is that transaction guaranteed to exist on the standby?

No. Asynchronous replication (the default) confirms a commit on the primary without waiting for the standby to receive or apply the corresponding WAL records, there's typically a small delay, often under a second, between a commit and its visibility on the standby. If the primary crashes in that window, before the WAL records reached the standby, that transaction is lost even though the client was already told it committed successfully. This is the specific, documented risk asynchronous replication accepts in exchange for not adding network round-trip latency to every commit.

Python Async Programming

How does asyncio achieve concurrency with a single thread?

asyncio runs an event loop that manages many coroutines cooperatively, a coroutine runs until it hits an `await` on an I/O operation, at which point it voluntarily yields control back to the event loop, which then runs another ready coroutine. While one coroutine is waiting on network I/O, the CPU isn't idle; the event loop is running other coroutines. This works because I/O waiting doesn't need the CPU at all; the concurrency comes from overlapping wait times, not from parallel execution, which is why it's a single thread the whole time and no locks are needed between coroutines.

Python Async Programming

Why does calling a blocking function inside an async function defeat the purpose of using asyncio?

A blocking call (synchronous file I/O, a synchronous HTTP request, `time.sleep`) occupies the single thread the event loop runs on, and unlike `await`, it does not yield control back, the entire event loop is frozen for the duration of that blocking call, so every other coroutine that could otherwise be making progress is stalled too. This is why async code requires async-compatible libraries throughout the I/O path; a single accidental blocking call anywhere in a hot path can silently serialize what was supposed to be concurrent work, and the bug often doesn't show up until real concurrent load exposes it.

Python Async Programming

When does asyncio actually help, and when is it not worth the added complexity?

asyncio helps specifically for I/O-bound workloads with many concurrent operations, handling thousands of simultaneous network connections, making many concurrent API calls, where most of the time is spent waiting, not computing. It does not help CPU-bound work at all, since the event loop is still single-threaded and a CPU-heavy coroutine blocks everything else exactly like any other blocking call; CPU-bound work needs `multiprocessing` or a separate process pool instead. For a workload with low concurrency or that's primarily CPU-bound, asyncio adds real complexity (colored functions, async-compatible libraries everywhere) without a corresponding benefit.

Frontend

The JavaScript Event Loop

Why every queued microtask runs before the next macrotask, ever, and how that one ordering rule explains why a Promise callback always logs before a setTimeout(fn, 0), no matter how it looks in the source.

The JavaScript Event Loop

Given a setTimeout(fn, 0) and a Promise.resolve().then(fn) registered in that order, which one runs first, and why?

The Promise callback runs first, even though the timeout was registered with a 0ms delay and appears to ask for the soonest possible execution. `setTimeout` queues a macrotask (a "task" in spec terms), while a Promise callback queues a microtask, and the event loop's rule is that the entire microtask queue is drained completely before the next macrotask is even pulled, regardless of registration order or the timeout value. A 0ms delay doesn't mean "immediately", it means "as the next task once the microtask queue is empty and the current call stack has finished."

The JavaScript Event Loop

What does "run to completion" mean for a single task or microtask, and why does it matter for reasoning about shared state?

Once a job (a task or a microtask) starts running, it executes entirely before any other job gets a chance to run, JavaScript cannot pause a running function partway through to let another callback interleave, the way a preemptively-scheduled thread in a language like C could be interrupted mid-function. This is what makes synchronous JavaScript code within a single function safe from data races on shared state without needing locks, whatever a function does to shared variables happens atomically from the perspective of any other queued job, even though the language is single-threaded and asynchronous.

The JavaScript Event Loop

If a microtask itself queues another microtask while it's running, does that new microtask wait for the next event loop iteration, or does it still run before the next macrotask?

It still runs before the next macrotask. The rule isn't "run the microtasks that were queued when this iteration started", it's "drain the microtask queue completely," and if executing a microtask adds another one, that new one is still part of the queue being drained. This means a chain of microtasks that keep scheduling more microtasks can, in principle, starve the event loop from ever reaching the next macrotask (a real, documented way to accidentally block timers and rendering), which is different from a single flat batch of microtasks all queued up front.

Databases

Database Replication

Why asynchronous replication can silently lose the most recent commits if the primary crashes, what synchronous_commit's three levels actually each guarantee, and how to measure replication lag instead of assuming it's small.

Backend

Python Web Frameworks Overview

How Flask, Django, and FastAPI trade minimalism, batteries-included structure, and async-first design differently, and how to actually choose based on project shape.

Azure Storage

What is the difference between locally redundant storage (LRS), zone-redundant storage (ZRS), and geo-redundant storage (GRS)?

LRS replicates data three times within a single datacenter; it protects against hardware failure but not a datacenter-level outage. ZRS replicates synchronously across three availability zones within one region, protecting against a single datacenter failure while keeping data within the region. GRS replicates asynchronously to a second, geographically distant region on top of LRS in the primary region, protecting against a regional disaster at the cost of the secondary copy lagging slightly behind (eventual, not synchronous, consistency) and being unreadable by default unless read access is explicitly enabled (RA-GRS).

Python Web Frameworks Overview

What does FastAPI provide that Flask does not, and what's the trade-off?

FastAPI is async-first (built on ASGI, not WSGI) and uses Python type hints to automatically generate request validation, serialization, and interactive OpenAPI documentation, a type-annotated function signature becomes both the API contract and its enforcement, with no separate schema to maintain by hand. The trade-off is that FastAPI assumes an async-first mental model and a type-hint-driven style throughout, which is a bigger shift for a team used to Flask's simpler, synchronous, un-opinionated style, and FastAPI has a smaller, younger ecosystem of plugins/extensions compared to Flask or Django's much longer history.

Python Web Frameworks Overview

Why does the choice between WSGI and ASGI matter when picking a Python web framework?

WSGI (Web Server Gateway Interface) is the traditional, synchronous interface between Python web applications and servers, one request is handled by one worker thread/process at a time, blocking for its duration. ASGI (Asynchronous Server Gateway Interface) extends that to support async request handling and other async protocols (WebSockets), letting a single worker handle many concurrent requests while they're waiting on I/O, the same underlying model as asyncio generally. Flask and Django historically are WSGI (Django has gained ASGI support); FastAPI is ASGI-native. The choice matters because it determines whether the framework can actually benefit from async I/O concurrency, or whether it's fundamentally a one-request-per-worker model regardless of async syntax used inside a handler.

Roadmap

Python Developer Roadmap

From syntax and data structures through tooling, testing, async programming, and web frameworks, the core path for a working Python developer, linked into Cloud Tech by Victor topic references.

Blog

How to Configure Azure File Sync

For many years, organizations have relied on traditional methods of sharing files, most commonly through mapped network drives connected to on‑premises Windows servers. This approach has served businesses well, especially those with domain‑joined computers and centralized IT infrastructure. However…

The CAP Theorem

A banking system typically favors CP behavior during a partition, while a chat application typically favors AP. What does each system actually do differently when a partition occurs, and why does the choice fit each use case?

A CP system, during a partition, pauses or rejects requests that can't be guaranteed consistent, a bank stopping a transfer rather than risking two nodes independently approving withdrawals against the same balance, since a duplicated or lost transaction is a correctness failure worse than a temporary outage. An AP system keeps responding during the partition, accepting the risk of temporarily inconsistent state, a chat app still accepting and displaying messages on both sides of a network split, reconciling them once the partition heals, because staying available and eventually consistent matters more to users than every message reappearing everywhere in a strict, immediate order.

Azure Networking

How does a Network Security Group (NSG) evaluate traffic rules?

An NSG contains a prioritized list of allow/deny rules, evaluated in priority order (lowest number first) until the first rule matching the traffic's source, destination, port, and protocol is found, that rule's action wins, and no further rules are evaluated. NSGs can attach to a subnet, a network interface, or both, and are stateful, meaning an allowed inbound connection's return traffic is automatically permitted without needing a matching outbound rule. Because evaluation stops at first match, rule priority ordering is the actual logic, a broad allow rule placed before a specific deny rule silently makes that deny unreachable.

Idempotency in Distributed Systems

A client sends a payment request, the network times out before a response arrives, and the client retries with the same idempotency key. What actually happens on the server?

If the original request already completed (successfully or even with an error like a 500) before the retry arrives, the server returns the exact same result it returned (or would have returned) the first time, the same status code and response body, without re-executing the underlying operation, so the customer isn't charged twice just because the client never saw the first response. This is the entire point of an idempotency key: it lets a client safely retry an operation whose actual outcome it's genuinely uncertain about (did the first request even reach the server? did it complete before the timeout?) without that retry risking a duplicate side effect.

Linux Users, Groups & sudo

In a sudoers rule like "ray rushmore = NOPASSWD: /bin/kill", what does each part of the rule mean, and what does NOPASSWD change?

The rule follows sudo's who/where/as-whom/what structure: `ray` is the user the rule applies to, `rushmore` is the host it applies on (sudoers rules can be host-scoped for a shared file across many machines), and `/bin/kill` is the specific command being granted, with no explicit run-as-user meaning the default (root). NOPASSWD changes the authentication requirement, by default sudo requires the invoking user to re-enter their own password before running a privileged command, and NOPASSWD removes that prompt for the commands it's attached to, which trades a real authentication check for convenience and should be scoped to specific, narrow commands rather than applied broadly.

LLM Evaluation & Reducing Hallucinations

Why is an evaluation suite necessary before shipping a prompt change, instead of just testing it manually on a few examples?

A prompt change can improve one success dimension while quietly breaking another, better accuracy but worse consistency, or improved tone at the cost of latency, and manually eyeballing a handful of examples won't reliably catch a regression on a dimension you weren't specifically looking at. An evaluation suite tests against a defined, ideally large set of cases, including deliberately hard edge cases like sarcasm or mixed sentiment, and scores every dimension that actually matters, which turns "it feels better" into a measurable, defensible, trackable claim, and catches regressions before they reach production rather than after.

Retrieval-Augmented Generation (RAG)

Why does a chunk like "The company's revenue grew by 3% over the previous quarter" cause a retrieval failure even if it's embedded correctly?

That sentence is only meaningful with context the isolated chunk doesn't carry, which company, which quarter, information that likely lived in a heading or preceding paragraph that didn't survive the chunking boundary. Embedded on its own, the chunk's vector represents a generic, context-free statement about revenue growth, which means it won't be retrieved reliably for a query about "ACME Corp Q2 2023 earnings" even though it's exactly the right chunk, because nothing in its embedding actually encodes that it's about ACME Corp or Q2 2023 at all.

Blog

How to Add a Secondary Domain Controller to an Existing Domain (Hyper-V Lab)

As part of strengthening an Active Directory Domain Services (AD DS) environment, this lab demonstrates how to add a secondary (additional) Domain Controller to an existing domain hosted on Windows Server using Hyper V. The objective is to introduce redundancy, replication, and improved availabilit…

Linux Process Management & systemd

In a systemd unit, what is the practical difference between Type=simple and Type=forking, and why does that distinction matter for dependency ordering?

With Type=simple, systemd considers the unit started the moment the main process is forked off, it does not wait for the application to finish its own initialization, so anything depending on that unit might start before the service is actually ready to handle requests. Type=forking expects the traditional daemon pattern, the initial process forks and exits once it judges its own startup complete, so systemd marks the unit started as soon as that original process exits successfully, while the actual daemon keeps running as a separate, now-orphaned process. That only tracks the daemonization handoff, not genuine application readiness, a process can exit believing setup is done while it is still finishing initialization in the background, so Type=forking is a better signal than Type=simple but still not a readiness guarantee. Type=notify is the one that actually is readiness-safe: the service explicitly calls sd_notify to tell systemd exactly when it's ready, rather than systemd inferring readiness from process exit behavior at all.

Rate Limiting Algorithms

Why would a system use a sliding window rate limiter instead of a token bucket, and what problem does it fix?

A naive fixed window (say, "100 requests per minute, resetting on the minute") allows a client to send 100 requests in the last second of one window and another 100 in the first second of the next, 200 requests in a two-second span despite the stated 100/minute limit, an artifact of the window boundary rather than actual demand. A sliding window rate limiter instead evaluates the limit over a continuously moving time range rather than fixed, discrete buckets, which avoids that boundary-doubling effect at the cost of typically more state to track (timestamps of recent requests, not just a single counter) compared to a token bucket's simpler accumulator model.

The CAP Theorem

MongoDB can be configured to behave more like a CP system or more like an AP system. What settings make that choice, and what are they actually trading?

Write concern and read preference are the actual levers: a write concern requiring acknowledgment from a majority of replicas favors consistency, a write isn't considered successful until enough nodes agree, at the cost of availability if too many nodes are unreachable during a partition. A looser write concern, or reading from secondaries that might lag behind the primary, favors availability, operations keep succeeding even when full replica agreement isn't achievable, at the cost of potentially reading or acknowledging data that isn't fully consistent across the cluster yet. This is exactly the CP-versus-AP trade-off CAP describes, expressed as a concrete, tunable configuration rather than an abstract theorem.

Azure Storage

How do access tiers (Hot, Cool, Archive) affect Blob Storage, and what do they not affect?

Access tiers change the cost trade-off between storage price and access/retrieval price: Hot has the highest storage cost but cheapest, immediate access; Cool has lower storage cost but a higher per-access cost and is meant for infrequently accessed data; Archive has the lowest storage cost but data must be rehydrated (a process taking hours) before it can be read at all. What tiers do not affect is durability, the redundancy option (LRS/ZRS/GRS) determines durability independently of which access tier a blob is in, so a Cool or Archive blob is exactly as durable as a Hot one with the same redundancy setting.

Consistent Hashing

Why does a naive `hash(key) % N` scheme for distributing keys across N servers fall apart the moment a server is added or removed?

With plain modulo hashing, the server a key maps to depends directly on the current value of N, since almost every key's `hash(key) % N` result changes the instant N changes to N-1 or N+1, even though the underlying hash values themselves didn't change at all. That means adding or removing a single server can remap the overwhelming majority of keys to different servers simultaneously, which for a cache means a massive wave of cache misses, and for a sharded store means a massive, unnecessary data-migration event, triggered by a change to just one server out of many.

Consistent Hashing

Why does a real ring hash implementation give each host many positions on the ring instead of just one, and what problem would a single position per host cause?

A host thrown onto the ring at just one point can end up, purely by chance, owning a disproportionately large or small arc of the ring if the hash values happen to land unevenly, since with few points there's no averaging effect smoothing out the randomness. Assigning each host many positions on the ring, scaled by that host's intended weight, so a double-weight host gets roughly twice as many ring entries as a single-weight one, averages out that randomness across many smaller arcs per host, producing a much more even overall traffic distribution than a single coin-flip-like placement per host would.

Container Image Scanning

Why does a smaller, minimal base image reduce security risk beyond just producing a smaller download?

Every package present in a base image is a package that can have a known vulnerability, and a full general-purpose distribution image bundles far more OS packages, libraries, and tools than most applications actually need at runtime. A minimal image (Alpine, a distroless image, or a multi-stage build's final stage) simply has fewer things in it that could ever show up in a vulnerability scan, which is a structural reduction in attack surface, not a mitigation that has to be maintained the way a scanner's exception list does.

Search results for “async” | Cloud Tech by Victor