Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: "nuget"
directory: "/"
schedule:
interval: "weekly"
day: "wednesday"
open-pull-requests-limit: 25
groups:
dotnet:
patterns:
- "*"
27 changes: 27 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Build
on:
workflow_dispatch:
push:
branches:
- main
- beta
- release/*
tags:
- v*
paths-ignore:
- docs/**
- README.md
- mkdocs.yml
- requirements.txt
permissions: write-all
jobs:
build:
uses: LayeredCraft/devops-templates/.github/workflows/[email protected]
with:
hasTests: true
useMtpRunner: true
testDirectory: "test"
dotnet-version: |
8.0.x
9.0.x
secrets: inherit
76 changes: 76 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Deploy Documentation

on:
push:
branches: [ main ]
paths:
- 'docs/**'
- 'mkdocs.yml'
- '.github/workflows/docs.yml'
pull_request:
branches: [ main ]
paths:
- 'docs/**'
- 'mkdocs.yml'
- '.github/workflows/docs.yml'

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Cache dependencies
uses: actions/cache@v4
with:
key: mkdocs-material-${{ hashFiles('requirements.txt') }}
path: ~/.cache/pip
restore-keys: |
mkdocs-material-

- name: Install dependencies
run: |
pip install mkdocs-material
pip install mkdocs-minify-plugin

- name: Setup Pages
id: pages
uses: actions/configure-pages@v4

- name: Build documentation
run: |
mkdocs build --clean

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: site

deploy:
if: github.ref == 'refs/heads/main'
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
20 changes: 20 additions & 0 deletions .github/workflows/pr-build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: PR Build

on:
pull_request:
branches:
- main
permissions: write-all
jobs:
build:
uses: LayeredCraft/devops-templates/.github/workflows/[email protected]
with:
solution: LayeredCraft.Lambda.AspNetCore.HostingExtensions.sln
hasTests: true
useMtpRunner: true
testDirectory: "test"
dotnetVersion: |
8.0.x
9.0.x
runCdk: false
secrets: inherit
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -416,3 +416,15 @@ FodyWeavers.xsd
*.msix
*.msm
*.msp

.idea
/site

# macOS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
54 changes: 54 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Overview

This is a .NET library that provides extensions and middleware for Amazon.Lambda.AspNetCoreServer.Hosting, designed specifically for AWS Lambda hosting environments. It delivers improved reliability, observability, and developer experience for ASP.NET Core applications running on AWS Lambda.

## Project Structure

- **src/LayeredCraft.Lambda.AspNetCore.HostingExtensions/** - Main library project containing middleware and extensions
- **Middleware/LambdaTimeoutLinkMiddleware.cs** - Core middleware that links Lambda timeout with HTTP request cancellation

## Key Architecture

The main component is `LambdaTimeoutLinkMiddleware` which provides timeout handling by:
- Creating a cancellation token that triggers on either client disconnect or Lambda timeout
- Replacing `HttpContext.RequestAborted` with a linked token during request processing
- Setting appropriate status codes (504 for timeout, 499 for client disconnect)
- Operating as pass-through in local development where `ILambdaContext` is unavailable

## Development Commands

### Build
```bash
dotnet build
```

### Test
```bash
dotnet test
```

### Restore Dependencies
```bash
dotnet restore
```

## Target Frameworks

The project targets both .NET 8.0 and .NET 9.0 (`net8.0;net9.0`).

## Key Dependencies

- **Amazon.Lambda.AspNetCoreServer** (v9.2.0) - AWS Lambda ASP.NET Core hosting
- **LayeredCraft.StructuredLogging** (v1.1.1.8) - Structured logging utilities

## Package Information

This is a packable library (NuGet package) with:
- MIT license
- SourceLink support for debugging
- Symbol packages (.snupkg) for enhanced debugging experience
- Version prefix: 2.0.1
29 changes: 29 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project>
<PropertyGroup>
<VersionPrefix>2.0.1</VersionPrefix>
<!-- SPDX license identifier for MIT -->
<PackageLicenseExpression>MIT</PackageLicenseExpression>

<!-- Other useful metadata -->
<RepositoryUrl>https://github.com/LayeredCraft/lambda-aspnetcore-hosting-extensions</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Authors>Nick Cipollina</Authors>
<PackageProjectUrl>https://github.com/LayeredCraft/lambda-aspnetcore-hosting-extensions</PackageProjectUrl>

<!-- NuGet.org specific -->
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<IsPackable>true</IsPackable>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>
100 changes: 100 additions & 0 deletions LayeredCraft.Lambda.AspNetCore.HostingExtensions.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{97C05F93-574D-41AA-A848-C4B7731FACC0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C52DAB93-ADC4-423B-9820-C705A55436A3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "git", "git", "{77FDD507-2994-4D64-8C35-232E81E75FF0}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
.github\dependabot.yml = .github\dependabot.yml
.github\workflows\build.yaml = .github\workflows\build.yaml
.github\workflows\docs.yml = .github\workflows\docs.yml
.github\workflows\pr-build.yaml = .github\workflows\pr-build.yaml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B22CDAC2-6A62-42F1-95FC-326861BED2A5}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
LICENSE = LICENSE
Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LayeredCraft.Lambda.AspNetCore.HostingExtensions", "src\LayeredCraft.Lambda.AspNetCore.HostingExtensions\LayeredCraft.Lambda.AspNetCore.HostingExtensions.csproj", "{789D3B32-3F92-4628-8416-08F3927E1B57}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{93154236-6904-4ED9-BF76-B0B8EDE6B578}"
ProjectSection(SolutionItems) = preProject
docs\index.md = docs\index.md
mkdocs.yml = mkdocs.yml
requirements.txt = requirements.txt
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{064CF7F9-2FC5-45EF-9718-346EC81E819A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "css", "css", "{72A05CD4-4462-4402-A972-49C30910EC82}"
ProjectSection(SolutionItems) = preProject
docs\assets\css\style.scss = docs\assets\css\style.scss
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{F52AB59C-12E2-4563-B811-888F9CFE884B}"
ProjectSection(SolutionItems) = preProject
docs\examples\index.md = docs\examples\index.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "middleware", "middleware", "{CEFF8EF9-B530-472C-A963-A953728322BB}"
ProjectSection(SolutionItems) = preProject
docs\middleware\lambda-timeout-middleware.md = docs\middleware\lambda-timeout-middleware.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LayeredCraft.Lambda.AspNetCore.HostingExtensions.Tests", "test\LayeredCraft.Lambda.AspNetCore.HostingExtensions.Tests\LayeredCraft.Lambda.AspNetCore.HostingExtensions.Tests.csproj", "{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{789D3B32-3F92-4628-8416-08F3927E1B57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Debug|Any CPU.Build.0 = Debug|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Debug|x64.ActiveCfg = Debug|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Debug|x64.Build.0 = Debug|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Debug|x86.ActiveCfg = Debug|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Debug|x86.Build.0 = Debug|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Release|Any CPU.ActiveCfg = Release|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Release|Any CPU.Build.0 = Release|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Release|x64.ActiveCfg = Release|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Release|x64.Build.0 = Release|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Release|x86.ActiveCfg = Release|Any CPU
{789D3B32-3F92-4628-8416-08F3927E1B57}.Release|x86.Build.0 = Release|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Debug|x64.ActiveCfg = Debug|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Debug|x64.Build.0 = Debug|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Debug|x86.ActiveCfg = Debug|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Debug|x86.Build.0 = Debug|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Release|Any CPU.Build.0 = Release|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Release|x64.ActiveCfg = Release|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Release|x64.Build.0 = Release|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Release|x86.ActiveCfg = Release|Any CPU
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{789D3B32-3F92-4628-8416-08F3927E1B57} = {97C05F93-574D-41AA-A848-C4B7731FACC0}
{064CF7F9-2FC5-45EF-9718-346EC81E819A} = {93154236-6904-4ED9-BF76-B0B8EDE6B578}
{72A05CD4-4462-4402-A972-49C30910EC82} = {064CF7F9-2FC5-45EF-9718-346EC81E819A}
{F52AB59C-12E2-4563-B811-888F9CFE884B} = {93154236-6904-4ED9-BF76-B0B8EDE6B578}
{CEFF8EF9-B530-472C-A963-A953728322BB} = {93154236-6904-4ED9-BF76-B0B8EDE6B578}
{EB5EF2DF-D345-4ACA-8017-DDBE8A056F2C} = {C52DAB93-ADC4-423B-9820-C705A55436A3}
EndGlobalSection
EndGlobal
Loading