今日已更新 166 条资讯 | 累计 40611 条内容
关于我们

标签:#architecture

找到 811 篇相关文章

AI 资讯

Upstream OSS Abandonment: An Engineering Decision Tree for EOL Dependencies

abandoned open source package vulnerability EOL dependency strategy fork vs patch security alert open source risk mitigation OSS abandonment decision tree tech lead security SLA abandoned dependency vulnerability end of life open source package unpatched upstream dependency replace abandoned OSS library isolate vulnerable code fork open source package internal maintenance OSS fork formal risk acceptance InstaSLA accepted risk logging vulnerability SLA deadline EOL package remediation open source dependency risk unmaintained open source library patching abandoned packages Upstream OSS Abandonment An Engineering Decision Tree for EOL Dependencies Back to blog The Silent Crisis of Upstream Abandonment Option 1: Replace the Dependency (The Ideal, but Costly Path) Option 2: Wrap and Isolate the Code (The Tactical Defense) Option 3: Fork and Maintain Internally (The Ownership Commitment) Option 4: Formal Risk Acceptance (The Compliance Reality) What 2025–2026 Actually Looked Like Conclusion Upstream OSS Abandonment: An Engineering Decision Tree for EOL Dependencies When an active vulnerability SLA deadline looms over a critical application, the standard playbook is straightforward: update the package, run the tests, merge the pull request. But what happens when the underlying open-source library has been quietly abandoned by its maintainer? Engineering teams are running into this exact scenario more often, and the numbers back that up: Veracode's 2025 State of Software Security report found that half of organizations carry critical security debt, and 70% of that debt originates from third-party code and the software supply chain. As the software supply chain grows more complex, the odds of an EOL package sitting somewhere in your dependency tree keep climbing. This article lays out a step-by-step decision framework for tech leads and security teams managing an EOL dependency when no upstream patch is coming — and updates it with what's actually happened in the open-source

2026-09-03 原文 →
AI 资讯

Beyond the Chatbot: Building Production AI Systems on AWS

AI apps have moved past simple chat boxes. Today's AI systems need agents, tools, memory, data, security, monitoring, and scale. The hard part is not calling an LLM API. The hard part is building a reliable system around that API call. 1. From LLM Demo to Production System A demo is simple: flowchart LR A[Prompt] --> B[Model] --> C[Response] A real production system looks very different: flowchart TD U[User] --> API[API] API --> APP[Application Layer] APP --> ORCH[AI Orchestration] ORCH --> LLM[LLM] ORCH --> TOOLS[Tools] ORCH --> RAG[RAG] ORCH --> MEM[Memory] ORCH --> GUARD[Guardrails] ORCH --> DATA[Data + Infrastructure] DATA --> OBS[Observability] Each box matters. If you skip Guardrails , bad input can hijack your system. If you skip Memory , every message re-explains itself and costs more tokens. If you skip Observability , you won't know why the system failed until a user tells you. The rest of this article walks through each box. 2. Where AWS Fits Instead of listing AWS services, let's match each one to a real problem. Problem AWS Service Why Need a foundation model Amazon Bedrock Managed access to multiple LLMs, no infra to run Store documents and files S3 Cheap, durable, scales easily Store app data RDS / Aurora / DynamoDB Structured data, users, sessions, transactions Search by meaning (retrieval) OpenSearch / pgvector Vector search for RAG Run code Lambda / ECS Serverless or container compute for your app logic Handle async work SQS / EventBridge Queue jobs, decouple slow tasks, avoid lost requests Watch the system CloudWatch Logs, metrics, alarms Keep it secure IAM / Secrets Manager Access control and safe storage of keys flowchart LR subgraph Compute L[Lambda / ECS] end subgraph Data S3[(S3)] DB[(RDS / DynamoDB)] VEC[(OpenSearch / pgvector)] end subgraph AI BR[Bedrock] end subgraph Ops CW[CloudWatch] SEC[IAM / Secrets Manager] end L --> BR L --> S3 L --> DB L --> VEC L --> CW L --> SEC 3. AI Agents Change the Architecture An agent doesn't just answer — i

2026-09-03 原文 →
AI 资讯

Building a multi-region routing system with Cloudflare Workers

We serve customers primarily in Australia, but we are now expanding to the USA. The timeline for launch is less than 2 months. This is now a race against time to design a multi-region routing system that fits all of our needs. Here is the story. Background Almost all of our customers were based in Oceania. We run our Kubernetes Cluster on GCP in Australia. Go microservices, federated GraphQL, gRPC services. 2 products - Tutoring and Schools. All designed for Australia. Then we expanded to the USA, which meant a new Kubernetes Cluster in US Central. The latency for serving US customers from Australia is an extra 200ms-300ms depending on network conditions - unacceptable. This would mean sharding the data by region, or does it? There are definitely ways to keep a unified dataset even across regions - though we did not need to do so. More on this later. What are the requirements If the only requirements were "Americans get served from America", we wouldn't be here discussing this, would we? Logged in users are served from their own region, wherever they happen to be in the world. Logged out users are routed geographically, as we have no other information to infer their actual region. Account Managers and Admins should be able to access both regions from one button, with a single account. Teaching materials opened via links from the Schools product must be shareable across both regions. Geography takes care of the logged out user, but nothing else. Using geography for a logged in user can be actively wrong. They might be travelling or simply using a VPN. Then comes the Admin; we have a lot of admin operations regarding curricula, which will be entirely separate for both clusters. Account Managers need to be able to see and modify information on both clusters. One admin should be able to access both clusters with a single account. We considered showing data of both clusters on one screen, but ruled it out as it may become too ambiguous or confusing, not worth the technic

2026-09-02 原文 →
AI 资讯

ATS Integration Architecture: What to Map Before You Sign

Most guides on choosing an applicant tracking system talk about features. This one is about the layer that actually determines whether the platform survives contact with your stack: integrations. If you're the technical person pulled into an ATS evaluation, this is the part your non-technical colleagues will underestimate — and the part that generates the most post-contract pain. Here's how to map it properly. 1. Inventory every data flow, not every tool Don't list “tools.” List directional data flows. For each system, write down what data moves, which direction, and how often: ●HRIS — candidate → employee record handoff on hire (bidirectional ideally) ●Payroll — new-hire data push (one-way, event-triggered) ●Background screening — order + status callback (bidirectional, webhook-driven) ●Calendar (Google/Microsoft) — interview scheduling + availability sync ●Video interview tools — scheduling links out, recordings/scores back ●Job boards / distribution — posting syndication out, application ingestion back The “direction + trigger” framing exposes gaps that a flat tool list hides. 2. Classify each integration by mechanism Not all “integrations” are equal. Push the vendor to tell you which of these each connection actually uses: ●Native pre-built integration — maintained by the vendor, lowest overhead ●Public REST API — you (or middleware) build and maintain it ●iPaaS / middleware (Workato, Merge.dev, etc.) — flexible, adds cost + a dependency ●Flat-file / SFTP batch — a red flag in 2025 for anything real-time ●“On the roadmap” — treat as does not exist A “yes, we integrate with X” that turns out to be a nightly CSV export is a very different thing from a webhook-driven bidirectional sync. 3. Interrogate the API itself If any integration will run through the public API, evaluate it like you'd evaluate any dependency: ●Is it REST/GraphQL, documented, and versioned? ●Rate limits — do they survive a high-volume hiring event? ●Webhooks for state changes, or are you stuck

2026-09-02 原文 →
AI 资讯

Building With AI When You Don't Know the Architecture: A Survival Guide

I have spent the better part of the last five years watching the relationship between developers and their tools mutate at a pace that most of us are still struggling to internalize, and if there is one pattern that repeats itself in almost every codebase I get pulled into for a review, it is this: a junior developer or a solo founder leaned heavily on an AI coding assistant to ship something functional, the thing genuinely worked in the demo, and then six weeks later the entire system started buckling under its own weight because nobody, including the AI, was thinking about architecture at the time the first line of code was written. This is not a criticism of AI tools, and it is definitely not a criticism of the people using them, because I think leaning on AI to move fast is one of the most rational decisions a resource-constrained developer can make in 2026. The problem is not the tool. The problem is that most people never learned how to ask an AI system to think architecturally, because architectural thinking was never explicitly taught to them in the first place, and AI assistants are extremely good at answering the question you asked while being completely indifferent to the question you should have asked. So this guide is my attempt to hand you the mental checklist that I use, refined over years of both writing production systems by hand and increasingly delegating large portions of that work to AI pair programmers. I am going to be deliberately thorough here rather than punchy, because the whole point of architecture is that it rewards patience and punishes shortcuts, and a survival guide that reads like a listicle would betray the subject matter. Why "vibe architecture" collapses later rather than immediately The dangerous thing about building a system with an AI assistant when you do not understand architecture yourself is that the failure mode is deferred. A missing index does not matter until your table has real data in it. A tightly coupled service do

2026-09-02 原文 →
AI 资讯

A Product Is Not Finished When the Frontend Is Finished

These articles come from lessons learned while building Eterna Clarity and the operating system I use to run it. Some of the most misleading moments in building software happen when the page looks finished. The button is there. The layout is polished. The flow works in a test account. The code has been merged. It is very easy to look at that and think the product has moved forward. Then production reminds you that a product is larger than its frontend. I learned this repeatedly while building Eterna Clarity. A customer-facing change could depend on application code, a database function, authentication, storage rules, an email template, environment configuration and the way a demo account was isolated from real customer data. If one of those pieces stayed behind, the screenshot could be correct while the product was not. That changed the way I think about releases. A release is not “the code shipped.” A release is the smallest complete set of owned systems that have to advance together for the accepted behavior to become true in production. The browser can hide a lot of unfinished work Frontend work is unusually visible. That makes it easy to use as a proxy for progress. Back-end state is less visible. So are permissions, production configuration, storage policy, transactional email, tenant boundaries and data migrations. They tend to reveal themselves only when something goes wrong. That asymmetry can create a strange kind of false confidence. A team can spend hours polishing the thing a customer sees while the systems underneath it still describe an older product. In Eterna, the correction was to stop treating the repository as the whole release. Source code still matters. It is simply one owner among several. If a new customer flow requires a database change, the production database has to advance. If it requires a new authentication behavior, the production auth configuration has to advance. If it depends on storage permissions, those permissions have to exist in

2026-09-02 原文 →
AI 资讯

Property Moderation Router: Compare 3 Startup API Token Costs with One Key

Short answer: for a property-management startup, the cheapest one-key router is the one that minimizes cost per correctly classified moderation report on your own replay set while preserving a provider-neutral request, response, and error contract. Raw token rates alone cannot make that choice. Choice Best fit Main catch Measure first Managed multi-provider router Small team optimizing time-to-first-call Another control plane owns the routing boundary Valid classifications per dollar Self-hosted gateway Team that needs policy and telemetry under its control You own upgrades, capacity, and incident response Operator hours plus inference cost Thin in-app adapters Narrow model set and strict contract control Every new capability adds adapter work Change lead time and test burden My default for an early startup app is a managed router behind a tiny internal interface, with request fixtures stored outside the router. Choose the self-hosted runner-up when data-path control or custom routing policy is more important than low configuration overhead. Choose direct adapters when the application genuinely uses only a small, stable slice of each provider API. This is a decision about portability, not a hunt for a permanent lowest price. OpenAI, Claude, and Gemini differ in message shapes, structured-output behavior, usage accounting, and model lifecycle. A shared API key removes credential sprawl; it doesn't erase those differences. How should a startup app compare token cost across one-key routers? Start with the unit of work: one moderation report reaching a human reviewer with a valid label, confidence, rationale, and trace ID. A property manager does not buy tokens for their own sake. They need reports such as harassment , fraud , safety , or noise triaged consistently enough that urgent cases rise and ambiguous cases stay in the human queue. The useful equation is: effective cost = inference charges + router charges + retries + invalid-output handling + operational labor T

2026-09-02 原文 →
开发者

How an Abandoned Client Project Became My Proudest Showcase

In the first part of this series , I walked through the technical grit of rebuilding a musician's web platform from scratch—spending over 320 hours fixing legacy WordPress code, writing custom CLI tools with Node.js and FFmpeg, and crafting a lightweight Vanilla JS SPA router. If Part 1 was about the engineering side , Part 2 is about the human side : scope creep, irrational client expectations, and why finishing an "abandoned" project is sometimes the ultimate test of a developer’s character. "Appetite Comes With Eating": How a Volunteer Portfolio Case Turned Into Scope Creep They say the road to hell is paved with good intentions. We stepped into this project on pure enthusiasm. The agreement was simple: we help an independent artist build a sleek web presence for free, and in return, we get a real-world production case for our engineering portfolios. Win-win, right? At the beginning, everything was smooth. The client was absolutely thrilled with the initial UI/UX prototypes. But as soon as the application was actually hosted and brought to life, the "appetite" started growing exponentially: Phase 1 (Initial tweaks): "Can we change the album cover art?" — Sure thing. It's your music, your Bandcamp embed—done. Phase 2 (The Breaking Point): "The fonts don't feel right... can we rewrite the copy?" This was the final straw. Keep in mind: we had repeatedly confirmed typography and styling choices with the client earlier, and everything had been approved. When my teammate David politely informed the client that fundamental UI changes were outside the scope of our volunteer agreement, the client responded with: "Just show me where the files are, and I'll change the fonts myself." For anyone who works in web development, this was the ultimate ironic punchline. Changing fluid typography, responsive SCSS breakpoints, and layout variables isn't like picking a font in Microsoft Word. Knowing that the client had previously struggled to set up a basic Bandcamp profile, we wishe

2026-09-01 原文 →
AI 资讯

A memory server remembers your conversation. That is not the same as knowing your code.

Before publishing: set published: true , and check canonical_url — the article must exist at that URL on the site first. Without it this competes with the original in search instead of pointing at it. Tags are from the verified top-1,000 list; mcp was not in that cache and is not used here. A session ends. Your agent had worked out, over forty minutes, that the retry logic lives in one service and the thing that gives up on it lives in another, that the queue name is spelled two different ways, and that the person to ask about any of it left last year. Tomorrow you open a new session and it knows none of that. Neither does your colleague's session. Neither does the agent reviewing the pull request that comes out of it. It is the same forty minutes a new engineer spends in week one, and the same forty minutes the README would have saved if it were still true. It is why a manager asking "where is this up to" has to interrupt someone who knows. The knowledge exists; it has nowhere to live but in people and chat logs. The reflex is to reach for memory. That reflex is worth interrogating, because there are two different problems hiding under one word, and only one of them is what memory servers are for. What MCP actually specifies It helps to be exact, because "MCP memory" gets said as though it were a feature of the protocol. It is not — and the current revision makes that harder to miss rather than easier. Read the base protocol's own three-line summary in revision 2026-07-28 : JSON-RPC message format, stateless, self-contained requests , per-request capability negotiation. Servers offer three features — Resources, Prompts and Tools. Clients offer one: Elicitation. Sampling and Roots, which used to make that three, were deprecated in this same revision under SEP-2577, along with Logging and Dynamic Client Registration; the migration note against Sampling reads "integrate directly with LLM provider APIs". There is no memory primitive and no persistence primitive. There

2026-09-01 原文 →
AI 资讯

Every Scan is A Write

What building a warehouse management system taught me about the data operational software leaves behind — and the engineering it takes to make that data trustworthy. The second that outlives itself A picker holds a handheld scanner, points it at a carton, and pulls the trigger. There's a beep. They type 10, confirm, and move to the next location. The whole thing takes about a second. For a long time I thought of my job as making that second work. I built the screen, the endpoint behind it, the repository behind that. My definition of done was that the user completed the workflow, the API returned success, and the right rows landed in the database. What changed my thinking was noticing what was still there afterwards. The screen closes, the session ends, the app ships a new version, the picker changes jobs, the device is replaced. The row stays — and the row isn't a record of a UI interaction. It's a durable claim about the physical world: at this time, this person, on this device, ten units of this product moved. The application is the instrument. The data is the measurement. A measurement is only ever worth what the instrument's precision allows. This article is about the gap between those two definitions of done, and the specific decisions — retry semantics, timestamps, identity, status codes, conflict resolution — that determine which side of it you land on. Almost all of them get made by application developers, inside feature work, long before anyone tries to analyze anything. What warehouse owners actually do with this data now Worth being concrete about the stakes first, because "data quality matters" is the kind of statement everyone agrees with and nobody acts on. What's changed isn't that owners suddenly became analytical. It's that operational systems started producing enough granular, attributed, time-stamped movement data that previously unanswerable questions became answerable. Inventory accuracy is a working-capital decision. Stock you can't trust is s

2026-09-01 原文 →
AI 资讯

Generating Binding Code Wasn't Enough: Moving Unity UI Composition to Compile Time

Source generators are often introduced as a way to remove boilerplate. That is useful, but it was not the main architectural reason FUI moved more of its Unity UI pipeline into Roslyn. The harder question begins after binding code has already been generated: does the runtime still need to scan assemblies, inspect attributes, resolve types, and reconstruct the relationship between a View, ViewModel, BindingContext, and Presenter? FUI's answer is to move that composition step to compile time. The generator does not stop at property notifications and binding callbacks. It also emits binding factories and strongly typed routes, so the Player runtime executes an already-validated object graph instead of rediscovering it. This article explains why that distinction matters, how the design evolved, and what the final architecture gains beyond the vague promise of “less reflection.” The original problem was repetitive protocol code Consider a settings screen with a title, a volume slider, a vibration toggle, and a close button. The ViewModel is small, but connecting it to the UI requires a surprisingly large protocol: propagate property changes to UI elements; propagate control changes back to the ViewModel; connect UI events to commands; perform initial synchronization; unsubscribe every handler during unbinding; construct the matching BindingContext and Presenter. None of these steps is individually difficult. The risk comes from repetition. A missing unsubscribe, an incompatible target member, or an incorrect string may remain invisible until that specific screen opens. The earliest code-generation experiment preserved in FUI's repository was an external FUICompiler executable. It targeted .NET 6, was published as a self-contained win-x64 tool, walked Roslyn syntax nodes, extracted binding attributes, and emitted BindingContext source. The central idea was already present: var classDeclarations = root . DescendantNodes () . OfType < ClassDeclarationSyntax >(); foreach ( v

2026-09-01 原文 →
AI 资讯

Why My React App Still Runs on Singleton Classes

React spent the last decade training developers that a class is a code smell. Class components got deprecated, hooks won, and "just write a function" became the default advice for almost everything. That advice runs into a wall the moment a piece of code has to run outside a component: an HTTP interceptor, an event listener, a background task, a deep-link handler. None of those have a render tree to sit inside, which means none of them can call a hook. That's not a style opinion. It's a hard constraint. It's also the reason core pieces of infrastructure in most non-trivial React codebases — auth tokens, feature flags, routing rules, device identity, analytics — end up as classes, usually singletons, imported directly instead of consumed through a hook or a context provider. The render-tree boundary problem A hook only exists while its component exists. useState allocates memory tied to a place in React's tree; the moment that component unmounts, the state is gone, and before it mounts, the state isn't reachable at all. That's fine for almost everything a component owns. It stops being fine the moment something outside the tree needs the same piece of state. Authentication is the clearest version of this. A typical setup keeps the access token in a hook, refreshed on a timer, exposed to whatever component needs it: export const useSessionTokens = (): UseSessionTokens => { const [ tokens , setTokens ] = React . useState < AuthTokens | null > ( null ); const refreshAccessToken = async () => { if ( ! tokens ?. refreshToken ) return ; const newTokens = await refreshAndSetTokens ({ refreshToken : tokens . refreshToken }); setTokens ( newTokens ); return newTokens ; }; // ... return { tokens , refreshAccessToken , /* ... */ }; }; Perfectly normal hook. The problem shows up one layer down: an HTTP client's request interceptor is a plain function, registered once at app boot, running completely outside React's render tree. It can't call useSessionTokens() — it isn't a compon

2026-09-01 原文 →
AI 资讯

Agents or a proxy: the access-control decision you make before you compare any features

Disclosure: I work on Tessera, which is one of the proxy-shaped tools. Both shapes are legitimate and I try to be fair to the other one below. Most comparisons of access-control tools start with feature tables. That is the wrong end. The decision that actually determines whether a rollout finishes is the deployment shape, and there are only two. Shape one: agents and certificates You run an internal certificate authority. Hosts are configured to trust it. Users get certificates that expire in a few hours. For Kubernetes, an agent runs inside the cluster and brokers access from there. What this buys you is genuinely good. Expiry does revocation automatically, which removes the human step that fails. The credential on the user's laptop is worthless tomorrow. The model scales well because the CA does not sit in the data path — once the certificate is issued, the user talks to the target directly, so there is no proxy to size and no bandwidth to plan. What it costs is that you have to change production before you get anything. sshd_config gets rewritten across the estate to add TrustedUserCAKeys . An agent gets deployed into every cluster. In some setups the tool's binary is copied onto hosts. None of that is technically hard. It is organisationally hard. You need a change window, sign-off from whoever owns those hosts, and a rollback plan — for a project whose entire benefit is "nothing bad will happen later". That conversation is where access-control rollouts stall, and it stalls most reliably in exactly the organisations that need the tool most: the ones where nobody is quite sure who owns which box. The other cost is that the CA private key becomes the most sensitive object your company owns, and now you operate a CA. Shape two: a proxy The credential stays on a controller. The user authenticates to the controller. The controller opens its own connection to the target, authenticates with the real credential, and relays. The target sees a normal connection from a nor

2026-09-01 原文 →
AI 资讯

Domain-Driven Design for Microservices: Building Scalable Systems with Clear Domain Boundaries

Domain-Driven Design for Microservices: Building Scalable Systems with Clear Domain Boundaries Introduction Domain-Driven Design (DDD) isn't just another architecture pattern—it's a philosophy that aligns technical decisions with business reality. When building microservices at scale, DDD becomes essential. Without it, you end up with services that don't respect business domains, unclear responsibilities, and integration nightmares. Why DDD Matters for Microservices Microservices force you to make decisions about boundaries. The question isn't whether you'll decompose your system—it's whether you'll do it thoughtfully using DDD principles, or accidentally create distributed monoliths. DDD answers three critical questions: Where should a service boundary exist? (Bounded Contexts) How do we communicate across services without coupling? (Domain Events, Anti-Corruption Layers) How do distributed teams understand the same problem? (Ubiquitous Language) Core Concept 1: Bounded Contexts A Bounded Context is a boundary within which a domain model is applicable. Each microservice should typically map to one or more Bounded Contexts. Java Example: E-commerce System // Ordering Context - Bounded Context 1 public class Order { private String orderId ; private List < OrderLineItem > lineItems ; private OrderStatus status ; // PENDING, CONFIRMED, SHIPPED, DELIVERED private LocalDateTime createdAt ; public void confirmOrder () { if ( this . status != OrderStatus . PENDING ) { throw new InvalidOrderStatusException ( "Cannot confirm non-pending order" ); } this . status = OrderStatus . CONFIRMED ; } } // Inventory Context - Bounded Context 2 public class InventoryItem { private String skuId ; private Integer availableQuantity ; private Integer reservedQuantity ; public void reserveStock ( Integer quantity ) { if ( availableQuantity < quantity ) { throw new InsufficientStockException ( "Not enough stock to reserve" ); } this . reservedQuantity += quantity ; this . availableQuantity -

2026-09-01 原文 →
AI 资讯

AWS Lambda vs. Traditional Servers: When Serverless Actually Makes Sense

AWS Lambda vs. Traditional Servers : When Serverless Actually Makes Sense "Serverless" is one of the more misleading names in cloud computing — there are still servers, you just don't manage them directly. AWS Lambda lets you run code in response to events without provisioning or maintaining a server yourself, and it genuinely changes how certain kinds of applications get built. But it's not a universal replacement for traditional servers, and understanding exactly where each one wins is more useful than treating this as "the new way vs. the old way." What Actually Changes With Lambda A traditional server — whether it's a physical machine, a VM, or a container running continuously — is always on, always consuming resources, and always your responsibility to patch, scale, and monitor, whether or not it's actively doing anything useful at a given moment. AWS Lambda flips this model: your code runs only in response to a specific trigger (an HTTP request, a file upload, a scheduled event), runs for as long as it takes to complete, and then stops. You're not paying for idle time, and you're not managing an operating system, patching, or server-level scaling — AWS handles all of that underneath the function itself. Where Lambda Genuinely Wins Event-driven, intermittent workloads — a function that runs occasionally in response to specific events (a file upload triggering image processing, a scheduled nightly job) is often dramatically cheaper on Lambda than paying for a server that sits idle most of the time Automatic scaling with zero configuration — Lambda scales from zero to many concurrent executions automatically, without you provisioning capacity in advance Reduced operational overhead — no patching an operating system, no managing server-level security updates, no capacity planning for a specific function Fast setup for simple, isolated tasks — a single-purpose function can go from idea to deployed in a genuinely short amount of time Where Traditional Servers Still

2026-09-01 原文 →