Compare commits

...

10 Commits

37 changed files with 220 additions and 234 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,18 +15,6 @@ namespace TCC.Controllers
this.ImageService = imageService; this.ImageService = imageService;
} }
[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,6 +1,5 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using ProtoBuf; using tcc_app.Models;
using System.IO;
namespace TCC.Controllers namespace TCC.Controllers
{ {
@@ -24,25 +23,25 @@ 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")] [HttpPost("protobuf")]
public async Task<IActionResult> PostProtobuf() public async Task<IActionResult> PostProtobuf()
{ {
HelloWorld cliente; PersonProto person;
byte[] response; byte[] response;
using (var stream = Request.BodyReader.AsStream()) using (var stream = Request.BodyReader.AsStream())
{ {
cliente = ProtoBuf.Serializer.Deserialize<HelloWorld>(stream); person = ProtoBuf.Serializer.Deserialize<PersonProto>(stream);
} }
using (var stream = new MemoryStream()) using (var stream = new MemoryStream())
{ {
ProtoBuf.Serializer.Serialize(stream, cliente); ProtoBuf.Serializer.Serialize(stream, person);
response = stream.ToArray(); response = stream.ToArray();
} }
@@ -51,11 +50,4 @@ namespace TCC.Controllers
} }
} }
[ProtoContract()]
public class HelloWorld
{
[ProtoMember(1)]
public string Message { get; set; }
}
} }

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/a8pf5HZL/small-image.png && \ wget https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png && \
wget https://files.ivanch.me/api/public/dl/ZoZDck7M/big-image.png && \ wget https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png && \
wget https://files.ivanch.me/api/public/dl/URuFVrtX/video.mp4 && \ wget https://files.ivanch.me/api/public/dl/QdKvaeQI/video.mp4 && \
wget https://files.ivanch.me/api/public/dl/aeZqpr_F/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

@@ -10,15 +10,5 @@
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

@@ -1,23 +1,22 @@
FROM rust:latest FROM rust:1.77-buster as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bullseye-slim
WORKDIR /app WORKDIR /app
RUN apt-get update && apt-get -y install wget && \ RUN apt-get update && apt-get -y install wget && \
wget https://files.ivanch.me/api/public/dl/a8pf5HZL/small-image.png && \ wget https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png && \
wget https://files.ivanch.me/api/public/dl/ZoZDck7M/big-image.png && \ wget https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png && \
wget https://files.ivanch.me/api/public/dl/URuFVrtX/video.mp4 && \ wget https://files.ivanch.me/api/public/dl/QdKvaeQI/video.mp4 && \
wget https://files.ivanch.me/api/public/dl/aeZqpr_F/nginx.html wget https://files.ivanch.me/api/public/dl/YD4vmSsO/nginx.html && \
mkdir -p ./static && \
COPY . .
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,14 +1,31 @@
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 actix_protobuf::{ProtoBuf, ProtoBufResponseBuilder as _};
use actix_protobuf::*; use actix_protobuf::*;
use prost::Message; use prost::Message;
use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq, Eq, Message)] #[derive(Clone, PartialEq, Eq, Message)]
pub struct HelloWorld { pub struct PersonProtobuf {
#[prost(string, tag = "1")] #[prost(string, tag = "1")]
pub message: String 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")]
@@ -37,43 +54,20 @@ 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 {
let body = serde_json::json!({ HttpResponse::Ok().json(web::Json(msg))
"message": "Hello World!"
});
HttpResponse::Ok()
.json(body)
} }
#[post("/simulation/protobuf")] #[post("/simulation/protobuf")]
async fn simulation_protobuf(msg: ProtoBuf<HelloWorld>) -> impl Responder { async fn simulation_protobuf(msg: ProtoBuf<PersonProtobuf>) -> impl Responder {
println!("model: {:?}", msg.0);
HttpResponse::Ok().protobuf(msg.0) HttpResponse::Ok().protobuf(msg.0)
} }
#[get("/image/load-small-image")]
async fn load_small_image() -> Result<NamedFile> {
let real_path = "static/small-image.png";
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}"))
@@ -87,8 +81,6 @@ 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(simulation_harmonic_progression) .service(simulation_harmonic_progression)
.service(simulation_json) .service(simulation_json)

1
Express Submodule

Submodule Express added at 930a322dfa

View File

@@ -13,10 +13,10 @@ RUN apt-get update && \
mv bin/protoc /usr/local/bin/ && \ mv bin/protoc /usr/local/bin/ && \
rm -rf protoc-25.0-linux-x86_64.zip bin include readme.txt rm -rf protoc-25.0-linux-x86_64.zip bin include readme.txt
RUN wget https://files.ivanch.me/api/public/dl/a8pf5HZL/small-image.png && \ RUN wget https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png && \
wget https://files.ivanch.me/api/public/dl/ZoZDck7M/big-image.png && \ wget https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png && \
wget https://files.ivanch.me/api/public/dl/URuFVrtX/video.mp4 && \ wget https://files.ivanch.me/api/public/dl/QdKvaeQI/video.mp4 && \
wget https://files.ivanch.me/api/public/dl/aeZqpr_F/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,22 +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/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,5 +1,5 @@
from flask import request, Blueprint, jsonify from flask import request, Blueprint, jsonify
import helloworld_pb2 import person_pb2
simulation_blueprint = Blueprint('simulation_blueprint', __name__) simulation_blueprint = Blueprint('simulation_blueprint', __name__)
@@ -26,15 +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_helloworld(): def return_helloworld():
return simulation_controller.return_helloworld(), 200 data = request.json
return data, 200
@simulation_blueprint.route('/simulation/protobuf', methods=['POST']) @simulation_blueprint.route('/simulation/protobuf', methods=['POST'])
def return_protobuf(): def return_protobuf():
bytes_data = request.data bytes_data = request.data
helloworld = helloworld_pb2.MyObj() helloworld = person_pb2.Person()
helloworld.ParseFromString(bytes_data) helloworld.ParseFromString(bytes_data)
return helloworld.SerializeToString(), 200 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

View File

@@ -1,5 +0,0 @@
syntax = "proto3";
message MyObj {
string message = 1;
}

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;
}

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto # source: person.proto
# Protobuf Python Version: 4.25.0 # Protobuf Python Version: 4.25.0
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
@@ -14,13 +14,13 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10helloworld.proto\"\x18\n\x05MyObj\x12\x0f\n\x07message\x18\x01 \x01(\tb\x06proto3') 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() _globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'helloworld_pb2', _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'person_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
_globals['_MYOBJ']._serialized_start=20 _globals['_PERSON']._serialized_start=16
_globals['_MYOBJ']._serialized_end=44 _globals['_PERSON']._serialized_end=98
# @@protoc_insertion_point(module_scope) # @@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
protobuf>=4.25.0 protobuf==4.25.0

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"
@@ -52,7 +52,7 @@ services:
tcc-spring: tcc-spring:
image: tcc:spring image: tcc:spring
container_name: tcc-spring container_name: tcc-spring
build: ./springtcc build: ./Spring
restart: always restart: always
ports: ports:
- "9085:8080" - "9085:8080"

View File

@@ -1,7 +1,22 @@
import helloworld_pb2 import json
import person_pb2
helloworld = helloworld_pb2.MyObj() person_proto = person_pb2.Person()
helloworld.message = "Hello World!" 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'),
@@ -19,17 +34,14 @@ ENDPOINTS = {
'Spring': 'http://localhost:9085', 'Spring': 'http://localhost:9085',
} }
AVG_RUNS = 5 AVG_RUNS = 30
helloworld_pb2
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/nginx.html', 'GET', range(0, 30_000, 5000), None),
('/simulation/protobuf', 'POST', range(0, 30_000, 5000), helloworld.SerializeToString()),
] ]

View File

@@ -10,19 +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])
for i, median in enumerate(bp['medians']): box.set(facecolor=FRAMEWORKS_COLORS[i])
# median.set(color=FRAMEWORKS_COLORS[i])
median.set(color='white')
for i in range(len(FRAMEWORKS)): for i in range(len(FRAMEWORKS)):
bp['whiskers'][i*2].set(color=FRAMEWORKS_COLORS[i]) bp['whiskers'][i*2].set(color=FRAMEWORKS_COLORS[i])
bp['whiskers'][i*2 + 1].set(color=FRAMEWORKS_COLORS[i]) bp['whiskers'][i*2 + 1].set(color=FRAMEWORKS_COLORS[i])
for i in range(len(FRAMEWORKS)): for i in range(len(FRAMEWORKS)):
bp['caps'][i*2].set(color=FRAMEWORKS_COLORS[i]) bp['caps'][i*2].set(color=FRAMEWORKS_COLORS[i])
bp['caps'][i*2 + 1].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
@@ -39,40 +40,20 @@ def plot_graph(x_data, y_data, title, x_label, y_label, filename, y_lim = None):
for f in range(len(FRAMEWORKS)): 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))])
print(filename) ax.set(xlabel=x_data[j], xticklabels=['' for _ in range(len(FRAMEWORKS))])
# print(y_data) ax.margins(0.05)
for j in range(len(x_data)):
positions = [len(FRAMEWORKS)*j + i + 2*j for i in range(len(FRAMEWORKS))]
bp = boxplot(y_data[j], positions = positions, widths = 0.6, showfliers=False,
patch_artist=True)
all_positions.append(positions)
setBoxColors(bp) setBoxColors(bp)
if j % 2 == 1:
ax.set_facecolor('#f2f2f2')
for i in range(len(FRAMEWORKS)): # set title
medians = [] fig.suptitle(title)
for j in range(len(x_data)): fig.supxlabel(x_label)
medians.append(np.median(y_data[j][i])) fig.supylabel(y_label)
positions = [all_positions[x][i] for x in range(len(x_data))]
plt.plot(positions, medians, color=FRAMEWORKS_COLORS[i], marker='.', linestyle='--', linewidth=0.3)
avg_positions = []
for positions in all_positions:
avg = np.average(positions)
avg_positions.append(avg)
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)
@@ -85,6 +66,7 @@ def plot_graph(x_data, y_data, title, x_label, y_label, filename, y_lim = None):
plt.legend() plt.legend()
plt.tight_layout() plt.tight_layout()
fig.subplots_adjust(hspace=0, wspace=0)
plt.savefig(f'{filename}.png') plt.savefig(f'{filename}.png')
plt.clf() plt.clf()

View File

@@ -1,5 +0,0 @@
syntax = "proto3";
message MyObj {
string message = 1;
}

View File

@@ -15,8 +15,8 @@ def download_file(url):
def init(): def init():
if not os.path.exists('small-image.png'): if not os.path.exists('small-image.png'):
download_file('https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png') download_file('https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png')
if not os.path.exists('big-image.png'): if not os.path.exists('big-image.png'):
download_file('https://files.ivanch.me/api/public/dl/iFuXSNhw/big-image.png') download_file('https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png')
init() 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;
}

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto # source: person.proto
# Protobuf Python Version: 4.25.0 # Protobuf Python Version: 4.25.0
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
@@ -14,13 +14,13 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10helloworld.proto\"\x18\n\x05MyObj\x12\x0f\n\x07message\x18\x01 \x01(\tb\x06proto3') 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() _globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'helloworld_pb2', _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'person_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
_globals['_MYOBJ']._serialized_start=20 _globals['_PERSON']._serialized_start=16
_globals['_MYOBJ']._serialized_end=44 _globals['_PERSON']._serialized_end=98
# @@protoc_insertion_point(module_scope) # @@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

Submodule tcc-express deleted from 504b59278f