Compare commits

...

14 Commits

39 changed files with 531 additions and 660 deletions

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "Spring"]
path = Spring
url = git@github.com:horakhy/springtcc.git
[submodule "Express"]
path = Express
url = git@github.com:horakhy/tcc-express.git

8
.idea/.gitignore generated vendored
View File

@@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml generated
View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/tcc.iml" filepath="$PROJECT_DIR$/.idea/tcc.iml" />
</modules>
</component>
</project>

8
.idea/tcc.iml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -15,35 +15,6 @@ namespace TCC.Controllers
this.ImageService = imageService; this.ImageService = imageService;
} }
[HttpPost("blur")]
public async Task<IActionResult> BlurImage([FromQuery] int radius)
{
MemoryStream mstream = new MemoryStream();
await HttpContext.Request.Body.CopyToAsync(mstream);
mstream.Position = 0;
var result = ImageService.BoxBlurImage(mstream, radius);
mstream.Close();
var blurredImageStream = new MemoryStream();
result.Write(blurredImageStream);
blurredImageStream.Position = 0;
return File(blurredImageStream, "image/png");
}
[HttpGet("load-small-image")]
public async Task<IActionResult> GetSimpleImage()
{
return File(ImageService.GetSimpleImage(), "image/png");
}
[HttpGet("load-big-image")]
public async Task<IActionResult> GetBigImage()
{
return File(ImageService.GetBigImage(), "image/png");
}
[HttpPost("save-big-image")] [HttpPost("save-big-image")]
public async Task<IActionResult> SaveBigImage() public async Task<IActionResult> SaveBigImage()
{ {

View File

@@ -1,5 +1,5 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using TCC.Services; using tcc_app.Models;
namespace TCC.Controllers namespace TCC.Controllers
{ {
@@ -14,7 +14,7 @@ namespace TCC.Controllers
[HttpGet("harmonic-progression")] [HttpGet("harmonic-progression")]
public async Task<IActionResult> GetHarmonicProgression([FromQuery] int n) public async Task<IActionResult> GetHarmonicProgression([FromQuery] int n)
{ {
float sum = 0; double sum = 0;
for (int i = 1; i <= n; i++) for (int i = 1; i <= n; i++)
{ {
sum += 1.0f / i; sum += 1.0f / i;
@@ -23,10 +23,31 @@ namespace TCC.Controllers
return Ok(sum); return Ok(sum);
} }
[HttpGet("json")] [HttpPost("json")]
public async Task<IActionResult> GetJsonResponse() public async Task<IActionResult> PostJson([FromBody] PersonJson person)
{ {
return Ok(new { message = "Hello World!" }); return Ok(person);
}
[HttpPost("protobuf")]
public async Task<IActionResult> PostProtobuf()
{
PersonProto person;
byte[] response;
using (var stream = Request.BodyReader.AsStream())
{
person = ProtoBuf.Serializer.Deserialize<PersonProto>(stream);
}
using (var stream = new MemoryStream())
{
ProtoBuf.Serializer.Serialize(stream, person);
response = stream.ToArray();
}
await Response.Body.WriteAsync(response, 0, response.Length);
return new EmptyResult();
} }
} }
} }

View File

@@ -12,10 +12,10 @@ RUN dotnet restore
RUN dotnet build -c Release -o out RUN dotnet build -c Release -o out
RUN cd out && \ RUN cd out && \
wget https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png && \ wget https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png && \
wget https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png && \ wget https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png && \
wget https://files.ivanch.me/api/public/dl/nAndfAjK/video.mp4 && \ wget https://files.ivanch.me/api/public/dl/QdKvaeQI/video.mp4 && \
wget https://files.ivanch.me/api/public/dl/RzXwJG7o/nginx.html && \ wget https://files.ivanch.me/api/public/dl/YD4vmSsO/nginx.html && \
rm -rf runtimes && \ rm -rf runtimes && \
mkdir -p ./static && \ mkdir -p ./static && \
mv small-image.png ./static && \ mv small-image.png ./static && \

View File

@@ -0,0 +1,12 @@
namespace tcc_app.Models
{
public class PersonJson
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Friends { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
using ProtoBuf;
namespace tcc_app.Models
{
[ProtoContract()]
public class PersonProto
{
[ProtoMember(1)]
public string Name { get; set; }
[ProtoMember(2)]
public int Age { get; set; }
[ProtoMember(3)]
public List<string> Friends { get; set; }
[ProtoMember(4)]
public string Email { get; set; }
[ProtoMember(5)]
public string Phone { get; set; }
}
}

View File

@@ -1,76 +1,14 @@
using ImageMagick; namespace TCC.Services
namespace TCC.Services
{ {
public class ImageService public class ImageService
{ {
public ImageService() { } public ImageService() { }
public MagickImage BoxBlurImage(Stream imageStream, int radius)
{
var image = new MagickImage(imageStream);
image.GaussianBlur(radius, radius);
return image;
//var blurredImage = new MagickImage(image);
//blurredImage = BoxBlurImageSeparable(image, blurredImage, radius, 0);
//blurredImage = BoxBlurImageSeparable(blurredImage, blurredImage, 0, radius);
//return blurredImage;
}
private MagickImage BoxBlurImageSeparable(MagickImage image, MagickImage blurredImage, int radiusX, int radiusY)
{
var pixels = image.GetPixels();
var blurredPixels = blurredImage.GetPixelsUnsafe();
foreach (var pixel in pixels)
{
int x = pixel.X,
y = pixel.Y;
long rTotal = 0, gTotal = 0, bTotal = 0;
int pixelCount = 0;
for (int offsetY = -radiusY; offsetY <= radiusY; offsetY++)
{
for (int offsetX = -radiusX; offsetX <= radiusX; offsetX++)
{
int newX = x + offsetX;
int newY = y + offsetY;
if (newX >= 0 && newX < image.Width && newY >= 0 && newY < image.Height)
{
var pixelColor = pixels[newX, newY];
rTotal += pixelColor.GetChannel(0);
gTotal += pixelColor.GetChannel(1);
bTotal += pixelColor.GetChannel(2);
pixelCount++;
}
}
}
blurredPixels[x, y].SetChannel(0, Convert.ToUInt16(rTotal / pixelCount));
blurredPixels[x, y].SetChannel(1, Convert.ToUInt16(gTotal / pixelCount));
blurredPixels[x, y].SetChannel(2, Convert.ToUInt16(bTotal / pixelCount));
}
return blurredImage;
}
public void SaveImage(Stream fileStream) public void SaveImage(Stream fileStream)
{ {
var file = File.Create("image.png"); var file = File.Create("image.png");
fileStream.CopyToAsync(file); fileStream.CopyToAsync(file);
file.Close(); file.Close();
} }
public byte[] GetSimpleImage()
{
return File.ReadAllBytes("static/small-image.png");
}
public byte[] GetBigImage()
{
return File.ReadAllBytes("static/big-image.png");
}
} }
} }

View File

@@ -11,8 +11,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="13.2.0" /> <PackageReference Include="protobuf-net" Version="3.2.26" />
<PackageReference Include="Magick.NET.Core" Version="13.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

496
ActixAPI/Cargo.lock generated
View File

@@ -7,9 +7,10 @@ name = "ActixAPI"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"actix-files", "actix-files",
"actix-protobuf",
"actix-web", "actix-web",
"futures", "futures",
"magick_rust", "prost",
"qstring", "qstring",
"serde", "serde",
"serde_json", "serde_json",
@@ -67,7 +68,7 @@ dependencies = [
"actix-utils", "actix-utils",
"ahash", "ahash",
"base64", "base64",
"bitflags 2.4.0", "bitflags 2.4.1",
"brotli", "brotli",
"bytes", "bytes",
"bytestring", "bytestring",
@@ -101,7 +102,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.32", "syn 2.0.38",
]
[[package]]
name = "actix-protobuf"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a14dd296f850b814ca6f21d9a8ab92232887c07be2082562b5f3e33286f5b24d"
dependencies = [
"actix-web",
"derive_more",
"futures-util",
"prost",
] ]
[[package]] [[package]]
@@ -214,7 +227,7 @@ dependencies = [
"actix-router", "actix-router",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.38",
] ]
[[package]] [[package]]
@@ -234,21 +247,22 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.3" version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"getrandom", "getrandom",
"once_cell", "once_cell",
"version_check", "version_check",
"zerocopy",
] ]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.0.5" version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@@ -268,6 +282,12 @@ dependencies = [
"alloc-no-stdlib", "alloc-no-stdlib",
] ]
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]] [[package]]
name = "askama_escape" name = "askama_escape"
version = "0.10.3" version = "0.10.3"
@@ -297,32 +317,9 @@ dependencies = [
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.21.4" version = "0.21.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"
[[package]]
name = "bindgen"
version = "0.68.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078"
dependencies = [
"bitflags 2.4.0",
"cexpr",
"clang-sys",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn 2.0.32",
"which",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
@@ -332,9 +329,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.4.0" version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]] [[package]]
name = "block-buffer" name = "block-buffer"
@@ -347,9 +344,9 @@ dependencies = [
[[package]] [[package]]
name = "brotli" name = "brotli"
version = "3.3.4" version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f"
dependencies = [ dependencies = [
"alloc-no-stdlib", "alloc-no-stdlib",
"alloc-stdlib", "alloc-stdlib",
@@ -358,9 +355,9 @@ dependencies = [
[[package]] [[package]]
name = "brotli-decompressor" name = "brotli-decompressor"
version = "2.3.4" version = "2.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f"
dependencies = [ dependencies = [
"alloc-no-stdlib", "alloc-no-stdlib",
"alloc-stdlib", "alloc-stdlib",
@@ -374,9 +371,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
[[package]] [[package]]
name = "bytestring" name = "bytestring"
version = "1.3.0" version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72"
dependencies = [ dependencies = [
"bytes", "bytes",
] ]
@@ -391,32 +388,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clang-sys"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]] [[package]]
name = "convert_case" name = "convert_case"
version = "0.4.0" version = "0.4.0"
@@ -436,9 +413,9 @@ dependencies = [
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.9" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@@ -464,9 +441,12 @@ dependencies = [
[[package]] [[package]]
name = "deranged" name = "deranged"
version = "0.3.8" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3"
dependencies = [
"powerfmt",
]
[[package]] [[package]]
name = "derive_more" name = "derive_more"
@@ -506,32 +486,11 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "errno"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.27" version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide",
@@ -554,9 +513,9 @@ dependencies = [
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.28" version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@@ -569,9 +528,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.28" version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
@@ -579,15 +538,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.28" version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
[[package]] [[package]]
name = "futures-executor" name = "futures-executor"
version = "0.3.28" version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-task", "futures-task",
@@ -602,32 +561,32 @@ checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.28" version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.38",
] ]
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.28" version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.28" version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.28" version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@@ -668,12 +627,6 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.21" version = "0.3.21"
@@ -699,15 +652,6 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "home"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
dependencies = [
"windows-sys",
]
[[package]] [[package]]
name = "http" name = "http"
version = "0.2.9" version = "0.2.9"
@@ -757,6 +701,15 @@ dependencies = [
"hashbrown", "hashbrown",
] ]
[[package]]
name = "itertools"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
dependencies = [
"either",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.9" version = "1.0.9"
@@ -765,9 +718,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]] [[package]]
name = "jobserver" name = "jobserver"
version = "0.1.26" version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@@ -778,63 +731,34 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.147" version = "0.2.149"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
[[package]]
name = "libloading"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
[[package]] [[package]]
name = "local-channel" name = "local-channel"
version = "0.1.3" version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
"futures-util",
"local-waker", "local-waker",
] ]
[[package]] [[package]]
name = "local-waker" name = "local-waker"
version = "0.1.3" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.10" version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"scopeguard", "scopeguard",
@@ -846,22 +770,11 @@ version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "magick_rust"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c912b69250bcd5d024852a1a75c567d3b5d881871a55b741018741632a921bf8"
dependencies = [
"bindgen",
"libc",
"pkg-config",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.6.3" version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]] [[package]]
name = "mime" name = "mime"
@@ -879,12 +792,6 @@ dependencies = [
"unicase", "unicase",
] ]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.7.1" version = "0.7.1"
@@ -896,9 +803,9 @@ dependencies = [
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.8.8" version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
@@ -906,16 +813,6 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.32.1" version = "0.32.1"
@@ -943,9 +840,9 @@ dependencies = [
[[package]] [[package]]
name = "parking_lot_core" name = "parking_lot_core"
version = "0.9.8" version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@@ -960,12 +857,6 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.0" version = "2.3.0"
@@ -990,6 +881,12 @@ version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.17" version = "0.2.17"
@@ -997,22 +894,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "prettyplease" name = "proc-macro2"
version = "0.2.15" version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [ dependencies = [
"proc-macro2", "unicode-ident",
"syn 2.0.32",
] ]
[[package]] [[package]]
name = "proc-macro2" name = "prost"
version = "1.0.66" version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d"
dependencies = [ dependencies = [
"unicode-ident", "bytes",
"prost-derive",
]
[[package]]
name = "prost-derive"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32"
dependencies = [
"anyhow",
"itertools",
"proc-macro2",
"quote",
"syn 2.0.38",
] ]
[[package]] [[package]]
@@ -1065,18 +975,18 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.3.5" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
] ]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.9.5" version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@@ -1086,9 +996,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.3.8" version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@@ -1097,9 +1007,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.7.5" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
@@ -1107,12 +1017,6 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.4.0" version = "0.4.0"
@@ -1122,19 +1026,6 @@ dependencies = [
"semver", "semver",
] ]
[[package]]
name = "rustix"
version = "0.38.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662"
dependencies = [
"bitflags 2.4.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.15"
@@ -1149,35 +1040,35 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.18" version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.188" version = "1.0.190"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.188" version = "1.0.190"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.38",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.106" version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2" checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@@ -1198,21 +1089,15 @@ dependencies = [
[[package]] [[package]]
name = "sha1" name = "sha1"
version = "0.10.5" version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures",
"digest", "digest",
] ]
[[package]]
name = "shlex"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380"
[[package]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.4.1" version = "1.4.1"
@@ -1233,15 +1118,15 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.0" version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.5.4" version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys", "windows-sys",
@@ -1260,9 +1145,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.32" version = "2.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1271,12 +1156,13 @@ dependencies = [
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.28" version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5"
dependencies = [ dependencies = [
"deranged", "deranged",
"itoa", "itoa",
"powerfmt",
"serde", "serde",
"time-core", "time-core",
"time-macros", "time-macros",
@@ -1284,15 +1170,15 @@ dependencies = [
[[package]] [[package]]
name = "time-core" name = "time-core"
version = "0.1.1" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]] [[package]]
name = "time-macros" name = "time-macros"
version = "0.2.14" version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
dependencies = [ dependencies = [
"time-core", "time-core",
] ]
@@ -1314,9 +1200,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.32.0" version = "1.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
@@ -1331,9 +1217,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.8" version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
@@ -1345,11 +1231,10 @@ dependencies = [
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.37" version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [ dependencies = [
"cfg-if",
"log", "log",
"pin-project-lite", "pin-project-lite",
"tracing-core", "tracing-core",
@@ -1357,18 +1242,18 @@ dependencies = [
[[package]] [[package]]
name = "tracing-core" name = "tracing-core"
version = "0.1.31" version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [ dependencies = [
"once_cell", "once_cell",
] ]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.16.0" version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]] [[package]]
name = "unicase" name = "unicase"
@@ -1387,9 +1272,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.11" version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
@@ -1423,40 +1308,6 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.48.0" version = "0.48.0"
@@ -1523,6 +1374,26 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "zerocopy"
version = "0.7.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e50cbb27c30666a6108abd6bc7577556265b44f243e2be89a8bc4e07a528c107"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a25f293fe55f0a48e7010d65552bb63704f6ceb55a1a385da10d41d8f78e4a3d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
]
[[package]] [[package]]
name = "zstd" name = "zstd"
version = "0.12.4" version = "0.12.4"
@@ -1544,11 +1415,10 @@ dependencies = [
[[package]] [[package]]
name = "zstd-sys" name = "zstd-sys"
version = "2.0.8+zstd.1.5.5" version = "2.0.9+zstd.1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656"
dependencies = [ dependencies = [
"cc", "cc",
"libc",
"pkg-config", "pkg-config",
] ]

View File

@@ -8,8 +8,9 @@ edition = "2021"
[dependencies] [dependencies]
actix-web = "4" actix-web = "4"
actix-files = "0.6.2" actix-files = "0.6.2"
magick_rust = "0.19.1"
qstring = "0.7.2" qstring = "0.7.2"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1" serde_json = "1"
futures = "0.3" futures = "0.3"
actix-protobuf = "0.10.0"
prost = { version = "0.12", features = ["prost-derive"] }

View File

@@ -1,36 +1,22 @@
FROM rust:latest FROM rust:1.77-buster as builder
WORKDIR /app
ENV MAGICK_VERSION 7.1 COPY . .
RUN cargo build --release
RUN apt-get update \
&& apt-get -y install wget curl build-essential clang pkg-config libjpeg-turbo-progs libpng-dev
RUN apt update && apt install curl -y \
&& curl https://imagemagick.org/archive/ImageMagick.tar.gz | tar xz \
&& cd ImageMagick-${MAGICK_VERSION}* \
&& ./configure --with-magick-plus-plus=no --with-perl=no \
&& make \
&& make install \
&& cd .. \
&& rm -r ImageMagick-${MAGICK_VERSION}*
FROM debian:bullseye-slim
WORKDIR /app WORKDIR /app
RUN wget https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png && \ RUN apt-get update && apt-get -y install wget && \
wget https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png && \ wget https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png && \
wget https://files.ivanch.me/api/public/dl/nAndfAjK/video.mp4 && \ wget https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png && \
wget https://files.ivanch.me/api/public/dl/RzXwJG7o/nginx.html wget https://files.ivanch.me/api/public/dl/QdKvaeQI/video.mp4 && \
wget https://files.ivanch.me/api/public/dl/YD4vmSsO/nginx.html && \
COPY . . mkdir -p ./static && \
RUN cargo build --release && \
cp ./target/release/ActixAPI . && \
mv small-image.png ./static && \ mv small-image.png ./static && \
mv big-image.png ./static && \ mv big-image.png ./static && \
mv video.mp4 ./static && \ mv video.mp4 ./static && \
mv nginx.html ./static && \ mv nginx.html ./static
ldconfig /usr/local/lib
ENV LD_LIBRARY_PATH=/usr/local/lib COPY --from=builder /app/target/release/ActixAPI .
ENTRYPOINT ["./ActixAPI"] CMD ["./ActixAPI"]

View File

@@ -1,7 +1,32 @@
use qstring::QString; use qstring::QString;
use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder, HttpRequest, Result}; use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder, HttpRequest, Result};
use actix_files::NamedFile; use actix_files::NamedFile;
use magick_rust::MagickWand; use actix_protobuf::*;
use prost::Message;
use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq, Eq, Message)]
pub struct PersonProtobuf {
#[prost(string, tag = "1")]
pub name: String,
#[prost(int32, tag = "2")]
pub age: i32,
#[prost(string, repeated, tag = "3")]
pub friends: Vec<String>,
#[prost(string, tag = "4")]
pub email: String,
#[prost(string, tag = "5")]
pub phone: String,
}
#[derive(Deserialize, Serialize)]
pub struct PersonJson {
pub name: String,
pub age: i32,
pub friends: Vec<String>,
pub email: String,
pub phone: String,
}
#[get("/status/ok")] #[get("/status/ok")]
async fn hello() -> impl Responder { async fn hello() -> impl Responder {
@@ -29,64 +54,25 @@ async fn simulation_harmonic_progression(req: HttpRequest) -> impl Responder {
HttpResponse::Ok().body(format!("{}", sum)) HttpResponse::Ok().body(format!("{}", sum))
} }
#[get("/simulation/json")] #[post("/simulation/json")]
async fn simulation_json() -> impl Responder { async fn simulation_json(msg: web::Json<PersonJson>) -> impl Responder {
// body = {"message": "Hello World"} HttpResponse::Ok().json(web::Json(msg))
let body = serde_json::json!({
"message": "Hello World!"
});
HttpResponse::Ok()
.json(body)
} }
#[get("/image/load-small-image")] #[post("/simulation/protobuf")]
async fn load_small_image() -> Result<NamedFile> { async fn simulation_protobuf(msg: ProtoBuf<PersonProtobuf>) -> impl Responder {
let real_path = "static/small-image.png"; HttpResponse::Ok().protobuf(msg.0)
Ok(NamedFile::open(real_path)?)
}
#[get("/image/load-big-image")]
async fn load_big_image() -> Result<NamedFile> {
let real_path = "static/big-image.png";
Ok(NamedFile::open(real_path)?)
} }
#[post("/image/save-big-image")] #[post("/image/save-big-image")]
async fn save_big_image(image_data: web::Bytes) -> Result<HttpResponse> { async fn save_big_image(image_data: web::Bytes) -> Result<HttpResponse> {
// Write bytes to file
std::fs::write("image.png", &image_data).unwrap(); std::fs::write("image.png", &image_data).unwrap();
// Return the blurred image bytes
Ok(HttpResponse::Ok() Ok(HttpResponse::Ok()
.content_type("application/json") .content_type("application/json")
.body("{\"status\": 200}")) .body("{\"status\": 200}"))
} }
#[post("/image/blur")]
async fn blur_image(image_data: web::Bytes, req: HttpRequest) -> Result<HttpResponse> {
// Load the image from the incoming bytes
let mut wand = MagickWand::new();
wand.read_image_blob(&image_data).unwrap();
let query_str = req.query_string();
let qs = QString::from(query_str);
let radius = qs.get("radius").unwrap_or("5").parse::<f64>().unwrap_or(5.0);
// Blur the image
wand.blur_image(radius, radius).unwrap();
// Convert the image back to bytes
let blurred_image_bytes = wand.write_image_blob("png").unwrap();
// Return the blurred image bytes
Ok(HttpResponse::Ok()
.content_type("image/png")
.body(blurred_image_bytes))
}
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
println!("Hello, world!"); println!("Hello, world!");
@@ -95,12 +81,10 @@ async fn main() -> std::io::Result<()> {
App::new() App::new()
.route("/static/{filename:.*}", web::get().to(static_serve)) .route("/static/{filename:.*}", web::get().to(static_serve))
.service(hello) .service(hello)
.service(load_small_image)
.service(load_big_image)
.service(save_big_image) .service(save_big_image)
.service(blur_image)
.service(simulation_harmonic_progression) .service(simulation_harmonic_progression)
.service(simulation_json) .service(simulation_json)
.service(simulation_protobuf)
.app_data(web::PayloadConfig::new(1024 * 1024 * 1024)) .app_data(web::PayloadConfig::new(1024 * 1024 * 1024))
}) })
.bind(("0.0.0.0", 5000))? .bind(("0.0.0.0", 5000))?

1
Express Submodule

Submodule Express added at 930a322dfa

View File

@@ -6,12 +6,17 @@ ENV PYTHONUNBUFFERED=1
WORKDIR /app WORKDIR /app
RUN apt-get update && apt-get install -y imagemagick && apt-get install -y wget && ls RUN apt-get update && \
apt-get install -y wget unzip && \
wget https://github.com/protocolbuffers/protobuf/releases/download/v25.0/protoc-25.0-linux-x86_64.zip && \
unzip protoc-25.0-linux-x86_64.zip && \
mv bin/protoc /usr/local/bin/ && \
rm -rf protoc-25.0-linux-x86_64.zip bin include readme.txt
RUN wget https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png && \ RUN wget https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png && \
wget https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png && \ wget https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png && \
wget https://files.ivanch.me/api/public/dl/nAndfAjK/video.mp4 && \ wget https://files.ivanch.me/api/public/dl/QdKvaeQI/video.mp4 && \
wget https://files.ivanch.me/api/public/dl/RzXwJG7o/nginx.html && \ wget https://files.ivanch.me/api/public/dl/YD4vmSsO/nginx.html && \
rm -rf runtimes && \ rm -rf runtimes && \
mkdir -p ./static && \ mkdir -p ./static && \
mv small-image.png ./static && \ mv small-image.png ./static && \

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -5,36 +5,6 @@ from flask import request, Response, Blueprint, jsonify, send_file
image_blueprint = Blueprint('image_blueprint', __name__) image_blueprint = Blueprint('image_blueprint', __name__)
image_service = ImageService() image_service = ImageService()
@image_blueprint.route('/image/blur', methods=['POST'])
def blur_image():
radius = int(request.args.get('radius'))
image = request.get_data()
if radius and image:
return send_file(io.BytesIO(image_service.box_blur_image(image, radius)),
mimetype='image/png',
as_attachment=True,
download_name='blurred_image.png')
return "Bad request", 400
@image_blueprint.route('/image/load-small-image', methods=['GET'])
def get_simple_image():
return send_file(io.BytesIO(image_service.get_simple_image()),
mimetype='image/png',
as_attachment=True,
download_name='small-image.png')
@image_blueprint.route('/image/load-big-image', methods=['GET'])
def get_big_image():
return send_file(io.BytesIO(image_service.get_big_image()),
mimetype='image/png',
as_attachment=True,
download_name='big-image.png')
@image_blueprint.route('/image/save-big-image', methods=['POST']) @image_blueprint.route('/image/save-big-image', methods=['POST'])
def save_image(): def save_image():
image_service.save_image(request.get_data()) image_service.save_image(request.get_data())

View File

@@ -1,4 +1,5 @@
from flask import request, Blueprint, jsonify from flask import request, Blueprint, jsonify
import person_pb2
simulation_blueprint = Blueprint('simulation_blueprint', __name__) simulation_blueprint = Blueprint('simulation_blueprint', __name__)
@@ -25,6 +26,16 @@ def return_ok():
return str(sum), 200 return str(sum), 200
@simulation_blueprint.route('/simulation/json', methods=['GET']) @simulation_blueprint.route('/simulation/json', methods=['POST'])
def return_ok(): def return_helloworld():
return simulation_controller.return_helloworld(), 200 data = request.json
return data, 200
@simulation_blueprint.route('/simulation/protobuf', methods=['POST'])
def return_protobuf():
bytes_data = request.data
helloworld = person_pb2.Person()
helloworld.ParseFromString(bytes_data)
return helloworld.SerializeToString(), 200

View File

@@ -4,4 +4,4 @@ status_blueprint = Blueprint('status_blueprint', __name__)
@status_blueprint.route('/status/ok', methods=['GET']) @status_blueprint.route('/status/ok', methods=['GET'])
def return_ok(): def return_ok():
return 200 return '', 200

9
FlaskAPI/person.proto Normal file
View File

@@ -0,0 +1,9 @@
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
repeated string friends = 3;
string email = 4;
string phone = 5;
}

26
FlaskAPI/person_pb2.py Normal file
View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: person.proto
# Protobuf Python Version: 4.25.0
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cperson.proto\"R\n\x06Person\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03\x61ge\x18\x02 \x01(\x05\x12\x0f\n\x07\x66riends\x18\x03 \x03(\t\x12\r\n\x05\x65mail\x18\x04 \x01(\t\x12\r\n\x05phone\x18\x05 \x01(\tb\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'person_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_globals['_PERSON']._serialized_start=16
_globals['_PERSON']._serialized_end=98
# @@protoc_insertion_point(module_scope)

View File

@@ -1,3 +1,3 @@
Flask>=1.0 Flask==3.0
gunicorn>=19.9.0 gunicorn==19.9.0
Wand protobuf==4.25.0

View File

@@ -1,49 +1,7 @@
from wand.image import Image, Color
def box_blur_image_separable(image, radius_x, radius_y):
width, height = image.width, image.height
kernel_x_size = 2 * radius_x + 1
kernel_y_size = 2 * radius_y + 1
kernel_area = kernel_x_size * kernel_y_size
blurred_image = image.clone()
for y in range(height):
for x in range(width):
r_total, g_total, b_total = 0, 0, 0
for offset_y in range(-radius_y, radius_y + 1):
for offset_x in range(-radius_x, radius_x + 1):
new_x = x + offset_x
new_y = y + offset_y
if 0 <= new_x < width and 0 <= new_y < height:
pixel = image[new_x, new_y]
r_total += pixel.red_int8
g_total += pixel.green_int8
b_total += pixel.blue_int8
r_avg = int(r_total / kernel_area)
g_avg = int(g_total / kernel_area)
b_avg = int(b_total / kernel_area)
blurred_image[x, y] = Color(f'rgb({r_avg},{g_avg},{b_avg})')
return blurred_image
class ImageService: class ImageService:
def __init__(self): def __init__(self):
pass pass
def box_blur_image(self, img, radius):
with Image(blob=img) as image:
image.gaussian_blur(radius, radius)
return image.make_blob()
# blurred_image = box_blur_image_separable(image, radius, 0)
# blurred_image = box_blur_image_separable(blurred_image, 0, radius)
# return blurred_image.make_blob()
def get_simple_image(self): def get_simple_image(self):
with open("./static/small-image.png", "rb") as file: with open("./static/small-image.png", "rb") as file:
return file.read() return file.read()

1
Spring Submodule

Submodule Spring added at 1c28f5c8e3

View File

@@ -40,7 +40,7 @@ services:
tcc-express: tcc-express:
image: tcc:express image: tcc:express
container_name: tcc-express container_name: tcc-express
build: ./tcc-express build: ./Express
restart: always restart: always
ports: ports:
- "9084:5000" - "9084:5000"
@@ -49,3 +49,15 @@ services:
limits: limits:
cpus: '1' cpus: '1'
memory: 1GB memory: 1GB
tcc-spring:
image: tcc:spring
container_name: tcc-spring
build: ./Spring
restart: always
ports:
- "9085:8080"
deploy:
resources:
limits:
cpus: '1'
memory: 1GB

View File

@@ -1,8 +1,29 @@
import json
import person_pb2
person_proto = person_pb2.Person()
person_proto.name = "John Doe"
person_proto.age = 30
person_proto.friends.extend(["Jane Doe", "John Smith"])
person_proto.email = "john.doe@email.com"
person_proto.phone = "123-456-7890"
person_proto = person_proto.SerializeToString()
person_json = {
"name": "John Doe",
"age": 30,
"friends": ["Jane Doe", "John Smith"],
"email": "john.doe@email.com",
"phone": "123-456-7890"
}
person_json = json.dumps(person_json)
FRAMEWORKS = [ FRAMEWORKS = [
('Actix', 'tcc-actix', 'orange'), ('Actix', 'tcc-actix', 'orange'),
('ASP.NET', 'tcc-aspnet', 'blue'), ('ASP.NET', 'tcc-aspnet', 'blue'),
('Flask', 'tcc-flask', 'green'), ('Flask', 'tcc-flask', 'grey'),
('Express', 'tcc-express', 'red'), ('Express', 'tcc-express', 'red'),
('Spring', 'tcc-spring', 'green'),
] ]
ENDPOINTS = { ENDPOINTS = {
@@ -10,19 +31,17 @@ ENDPOINTS = {
'ASP.NET': 'http://localhost:9081', 'ASP.NET': 'http://localhost:9081',
'Flask': 'http://localhost:9082', 'Flask': 'http://localhost:9082',
'Express': 'http://localhost:9084', 'Express': 'http://localhost:9084',
'Spring': 'http://localhost:9085',
} }
AVG_RUNS = 5 AVG_RUNS = 30
API_REQUESTS = [ API_REQUESTS = [
('/status/ok', 'GET', range(0, 30_000, 5000), None), ('/status/ok', 'GET', range(0, 30_000, 5000), None),
('/simulation/harmonic-progression?n=100000', 'GET', range(0, 30_000, 5000), None), ('/simulation/harmonic-progression?n=100000', 'GET', range(0, 30_000, 5000), None),
('/simulation/json', 'GET', range(0, 30_000, 5000), None), ('/simulation/json', 'POST', range(0, 30_000, 5000), (person_json, "application/json")),
('/image/save-big-image', 'POST', range(0, 500, 50), open('big-image.png', 'rb').read()), ('/simulation/protobuf', 'POST', range(0, 30_000, 5000), (person_proto, "application/protobuf")),
('/image/load-small-image', 'GET', range(0, 30_000, 5000), None), ('/image/save-big-image', 'POST', range(0, 500, 50), (open('big-image.png', 'rb').read(), "image/png")),
('/static/small-image.png', 'GET', range(0, 30_000, 5000), None), ('/static/small-image.png', 'GET', range(0, 30_000, 5000), None),
('/image/load-big-image', 'GET', range(0, 500, 50), None),
('/static/big-image.png', 'GET', range(0, 500, 50), None), ('/static/big-image.png', 'GET', range(0, 500, 50), None),
('/static/video.mp4', 'GET', range(0, 10_000, 1_000), None),
('/static/nginx.html', 'GET', range(0, 30_000, 5000), None),
] ]

View File

@@ -10,8 +10,20 @@ FRAMEWORKS = [f for f, _, _ in FRAMEWORKS]
def setBoxColors(bp): def setBoxColors(bp):
for i, box in enumerate(bp['boxes']): for i, box in enumerate(bp['boxes']):
box.set(color=FRAMEWORKS_COLORS[i]) box.set(color=FRAMEWORKS_COLORS[i])
box.set(facecolor=FRAMEWORKS_COLORS[i])
for i in range(len(FRAMEWORKS)):
bp['whiskers'][i*2].set(color=FRAMEWORKS_COLORS[i])
bp['whiskers'][i*2 + 1].set(color=FRAMEWORKS_COLORS[i])
for i in range(len(FRAMEWORKS)):
bp['caps'][i*2].set(color=FRAMEWORKS_COLORS[i])
bp['caps'][i*2 + 1].set(color=FRAMEWORKS_COLORS[i])
for i, median in enumerate(bp['medians']):
median.set(color='white')
def plot_graph(x_data, y_data, title, x_label, y_label, filename, y_lim = None): def plot_graph(x_data, y_data, title, x_label, y_label, filename, y_lim = None):
print(filename)
old_x_data = x_data old_x_data = x_data
old_y_data = y_data old_y_data = y_data
@@ -22,42 +34,39 @@ def plot_graph(x_data, y_data, title, x_label, y_label, filename, y_lim = None):
if old_x_data[i] not in x_data: if old_x_data[i] not in x_data:
x_data.append(old_x_data[i]) x_data.append(old_x_data[i])
y_data.append([]) y_data.append([])
for f in range(2): for f in range(len(FRAMEWORKS)):
y_data[-1].append([]) y_data[-1].append([])
for f in range(2): for f in range(len(FRAMEWORKS)):
y_data[-1][f].append(old_y_data[f][i]) y_data[-1][f].append(old_y_data[f][i])
fig = figure() fig, axes = plt.subplots(ncols=len(x_data), sharey=True)
ax = axes()
all_positions = [] for ax, j in zip(axes, [i for i in range(len(x_data))]):
bp = ax.boxplot(y_data[j], showfliers=False, patch_artist=True, positions=[i for i in range(len(FRAMEWORKS))])
for j in range(len(x_data)): ax.set(xlabel=x_data[j], xticklabels=['' for _ in range(len(FRAMEWORKS))])
positions = [len(FRAMEWORKS)*j + i + 1 for i in range(len(FRAMEWORKS))] ax.margins(0.05)
bp = boxplot(y_data[j], positions = positions, widths = 0.6)
all_positions.append(positions)
setBoxColors(bp) setBoxColors(bp)
if j % 2 == 1:
ax.set_facecolor('#f2f2f2')
avg_positions = [] # set title
for positions in all_positions: fig.suptitle(title)
avg_positions.append(np.average(positions)) fig.supxlabel(x_label)
fig.supylabel(y_label)
ax.set_xticks(avg_positions)
ax.set_xticklabels([str(x) for x in x_data])
plt.title(title)
plt.xlabel(x_label)
plt.ylabel(y_label)
if y_lim: if y_lim:
plt.ylim(y_lim) plt.ylim(y_lim)
if filename.startswith('req'):
for i, framework in enumerate(FRAMEWORKS): for i, framework in enumerate(FRAMEWORKS):
h, = plt.plot([], c=FRAMEWORKS_COLORS[i], label=framework) h, = plt.plot([], c=FRAMEWORKS_COLORS[i], label=framework, marker='.', linestyle='--')
# h.set_visible(False) # h.set_visible(False)
plt.legend() plt.legend()
plt.tight_layout()
fig.subplots_adjust(hspace=0, wspace=0)
plt.savefig(f'{filename}.png') plt.savefig(f'{filename}.png')
plt.clf() plt.clf()
@@ -134,6 +143,8 @@ if __name__ == '__main__':
framework_name = 'ASP.NET' framework_name = 'ASP.NET'
endpoint_file = endpoint_name.replace('/', '') endpoint_file = endpoint_name.replace('/', '')
endpoint_name = '/' + endpoint_name.split('/')[-1]
filename = f'data/resource_ASP.NET_{endpoint_file}.csv' filename = f'data/resource_ASP.NET_{endpoint_file}.csv'
filename = filename.replace("?", "_") filename = filename.replace("?", "_")
generate_resource_graph(filename, framework_name, endpoint_name) generate_resource_graph(filename, framework_name, endpoint_name)

View File

@@ -1,4 +1,5 @@
import requests import requests
import os
def download_file(url): def download_file(url):
local_filename = url.split('/')[-1] local_filename = url.split('/')[-1]
@@ -13,5 +14,9 @@ def download_file(url):
return local_filename return local_filename
def init(): def init():
download_file('https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png') if not os.path.exists('small-image.png'):
download_file('https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png') download_file('https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png')
if not os.path.exists('big-image.png'):
download_file('https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png')
init()

9
scripts/person.proto Normal file
View File

@@ -0,0 +1,9 @@
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
repeated string friends = 3;
string email = 4;
string phone = 5;
}

26
scripts/person_pb2.py Normal file
View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: person.proto
# Protobuf Python Version: 4.25.0
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cperson.proto\"R\n\x06Person\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03\x61ge\x18\x02 \x01(\x05\x12\x0f\n\x07\x66riends\x18\x03 \x03(\t\x12\r\n\x05\x65mail\x18\x04 \x01(\t\x12\r\n\x05phone\x18\x05 \x01(\tb\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'person_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_globals['_PERSON']._serialized_start=16
_globals['_PERSON']._serialized_end=98
# @@protoc_insertion_point(module_scope)

31
scripts/protobuftest.py Normal file
View File

@@ -0,0 +1,31 @@
import person_pb2
import asyncio
import aiohttp
async def fetch(session):
obj = get_object()
# async with session.post('http://172.25.96.1:9090/simulation/protobuf', data=obj.SerializeToString(),
async with session.post('http://127.0.0.1:5000/simulation/protobuf', data=obj.SerializeToString(),
headers={"content-type": "application/protobuf"}) as resp:
print(resp.status)
data = await resp.read()
receiveObj = person_pb2.Person()
receiveObj.ParseFromString(data)
print(receiveObj)
async def go(loop):
async with aiohttp.ClientSession(loop=loop) as session:
await fetch(session)
def get_object():
obj = person_pb2.Person()
obj.name = "John Doe"
obj.age = 30
obj.friends.extend(["Jane Doe", "John Smith"])
obj.email = "john.doe@email.com"
obj.phone = "123-456-7890"
return obj
loop = asyncio.get_event_loop()
loop.run_until_complete(go(loop))
loop.close()

4
scripts/requirements.txt Normal file
View File

@@ -0,0 +1,4 @@
protobuf>=4.25.0
matplotlib
numpy
docker

View File

@@ -14,7 +14,7 @@ FRAMEWORK_NAME = ""
CONTAINER_NAME = "" CONTAINER_NAME = ""
URL_BASE = 'http://localhost:9090' URL_BASE = 'http://localhost:9090'
def send_request(url, method = 'GET', payload = None): def send_request(url, method = 'GET', data = None):
success = False success = False
responses = { responses = {
2: 0, # OK 2: 0, # OK
@@ -27,7 +27,9 @@ def send_request(url, method = 'GET', payload = None):
if method == 'GET': if method == 'GET':
response = requests.get(url) response = requests.get(url)
elif method == 'POST': elif method == 'POST':
response = requests.post(url, data=payload, headers={'Content-Type': 'image/png'}) payload = data[0]
content_type = data[1]
response = requests.post(url, data=payload, headers={'Content-Type': content_type})
except: except:
continue continue
success = response.status_code == 200 success = response.status_code == 200
@@ -74,8 +76,6 @@ def run_tests(endpoint, method, num_requests, metadata):
start_time = time.time() start_time = time.time()
futures = [] futures = []
#with requests.Session() as session:
# futures = [executor.submit(send_request, session, url) for _ in range(num_request)]
half = floor(num_request/2) half = floor(num_request/2)
for i in range(num_request): for i in range(num_request):
@@ -102,7 +102,7 @@ def run_tests(endpoint, method, num_requests, metadata):
record(files[0], num_request, f"{num_request/elapsed_time:.2f}") record(files[0], num_request, f"{num_request/elapsed_time:.2f}")
record_resource(files[1], num_request, cpu, ram) record_resource(files[1], num_request, cpu, ram)
time.sleep(3) time.sleep(30)
def get_resource_usage(): def get_resource_usage():
if CONTAINER_NAME == "": return 0, 0 if CONTAINER_NAME == "": return 0, 0
@@ -135,6 +135,8 @@ if __name__ == "__main__":
if not os.path.exists("data"): if not os.path.exists("data"):
os.mkdir("data") os.mkdir("data")
init()
for i in range(len(FRAMEWORKS)): for i in range(len(FRAMEWORKS)):
FRAMEWORK_NAME = FRAMEWORKS[i][0] FRAMEWORK_NAME = FRAMEWORKS[i][0]
CONTAINER_NAME = FRAMEWORKS[i][1] CONTAINER_NAME = FRAMEWORKS[i][1]

Submodule tcc-express deleted from 504b59278f