Skip to content

Commit

Permalink
Merge pull request #8 from Saetch/6-distribute-values-to-nodes-based-…
Browse files Browse the repository at this point in the history
…on-hashing-algorithm

6 distribute values to nodes based on hashing algorithm
  • Loading branch information
Saetch authored May 23, 2024
2 parents b6f40ee + 60e6dcd commit 263fcf9
Show file tree
Hide file tree
Showing 28 changed files with 2,222 additions and 221 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/github-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ jobs:
package-name: 'deightma_nodecs'
package-type: container
min-versions-to-keep: 1
- uses: actions/delete-package-versions@v5
with:
package-name: 'hasher_service'
package-type: container
min-versions-to-keep: 1
- run: |
docker push ghcr.io/saetch/deightma_coordinator:latest
- run: |
Expand All @@ -46,6 +51,8 @@ jobs:
docker push ghcr.io/saetch/deightma_master:latest
- run: |
docker push ghcr.io/saetch/deightma_nodecs:latest
- run: |
docker push ghcr.io/saetch/hasher_service:latest
build-client:
runs-on: Ubuntu-latest
steps:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ Cluster/bicubic_interpolation_service/target
Cluster/coordinator/target
Cluster/coordinator/.vs
Cluster/coordinator/.vscode
Cluster/hasher_service/target
Cluster/hasher_service/.vs
Cluster/hasher_service/.vscode
Cluster/hasher_service/.launch
token
25 changes: 25 additions & 0 deletions Cluster/Master/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/bin
**/charts
**/docker-compose*
**/compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
2 changes: 1 addition & 1 deletion Cluster/Master/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ RUN dotnet publish -p:PublishAot=true -p:StripSymbols=true -c Debug -o /app/publ

# Switch to the runtime image
FROM alpine:3.19 AS runtime
RUN apk add libc6-compat
RUN apk add libc6-compat --no-cache icu-libs

# Set the working directory inside the Docker image
WORKDIR /app
Expand Down
37 changes: 15 additions & 22 deletions Cluster/Master/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,9 @@ public class Program{

static int static_width_per_node = 2;
static int static_height_per_node = 2;
static bool use_dummy = true;

static int Main(String[] args){

if (Environment.GetEnvironmentVariable("USE_DUMMY") == "false") {
use_dummy = false;
}

var builder = WebApplication.CreateSlimBuilder(args);

Expand All @@ -30,7 +26,7 @@ static int Main(String[] args){
});

//configure the builder to accept external connections to the server ("0.0.0.0")
builder.WebHost.ConfigureKestrel(options => options.Listen(IPAddress.Any, 5552));
builder.WebHost.ConfigureKestrel(options => options.Listen(IPAddress.Any, 8080));


var app = builder.Build();
Expand All @@ -39,14 +35,12 @@ static int Main(String[] args){
app.MapGet("/getValue/{values}", async (string values) =>
{
try {
if (use_dummy)
{
var result = getDummyValue(values);
return Results.Ok(result);
}else{
var result = await getValue(values);
return Results.Ok(result);
}

var result = await getValue(values);
Console.WriteLine("Returning result: " + result);

return Results.Ok(result.Replace("\"", "'"));

} catch (Exception e) {
return Results.BadRequest(e.Message);
}
Expand All @@ -59,7 +53,7 @@ static int Main(String[] args){



static async Task<XYValues> getValue(String input){
static async Task<String> getValue(String input){
var inputs = input.Split('_');
if (inputs.Length != 2)
throw new ArgumentException("Input must be in the format 'x_y'");
Expand All @@ -71,8 +65,8 @@ static async Task<XYValues> getValue(String input){
int y_int = (int)Math.Round(y_double);

String node_name = find_correct_node(x_int, y_int);
double result_value = await get_value_from_node(node_name, input);
return new XYValues {x = x_double, y = y_double, value = result_value};
String result_value = await get_value_from_node(node_name, input);
return result_value;
}


Expand Down Expand Up @@ -111,7 +105,7 @@ static XYValues getDummyValue(String input){



static async Task<double> get_value_from_node(String name, string input)
static async Task<String> get_value_from_node(String name, string input)
{
// Construct the URL for the external API endpoint
string apiUrl = $"http://"+name+":5552/getValue/"+input;
Expand All @@ -128,12 +122,8 @@ static async Task<double> get_value_from_node(String name, string input)
// Read the response content as a string
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine("Received response: " + responseBody);
XYValues? result = JsonSerializer.Deserialize<XYValues>(responseBody);
if (result == null)
throw new Exception("Error parsing response from node");

Console.WriteLine("Received value: " + result.value);
return result.value;
return responseBody;
}
}
}
Expand All @@ -155,7 +145,10 @@ class XYValues


[JsonSerializable(typeof(XYValues[]))]
[JsonSerializable(typeof(XYValues))]
[JsonSerializable(typeof(String))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

4 changes: 4 additions & 0 deletions Cluster/Node_cs/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[*.cs]

# CS8600: Converting null literal or possible null value to non-nullable type.
dotnet_diagnostic.CS8600.severity = warning
75 changes: 66 additions & 9 deletions Cluster/Node_cs/ApiConfig.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;

using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json.Serialization;


namespace Node_cs
{
public class ApiConfig
{

public Dictionary<Tuple<int, int>, double> savedValues = new Dictionary<Tuple<int, int>, double>();
public Dictionary<Tuple<int, int>, String> exteriorValuesInNodes = new Dictionary<Tuple<int, int>, String>();
public String BICUBIC_INTERPOLATION_SERVICE_URL = "http://bicubic_interpolation_service:8080/calculate";
public String hostname = Environment.GetEnvironmentVariable("HOSTNAME");
public String COORDINATOR_SERVICE_URL = "coordinator";
public int PORT = 8080;

public ushort ownerHash = 0;
public int initializeConfigValues()
{
Console.WriteLine("hostname is: "+ this.hostname);
Expand Down Expand Up @@ -52,7 +51,6 @@ public int initializeConfigValues()
public WebApplication setupServer(){

var builder = WebApplication.CreateSlimBuilder();

builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
Expand Down Expand Up @@ -114,8 +112,35 @@ private void registerRequests(WebApplication app)
return Results.BadRequest(e.Message);
}
});
app.MapGet("/getAllSavedValues", () =>
{
//go through all keys in savedvalues
//return a list of all keys and values
List<XYValues> values = new List<XYValues>();
foreach (KeyValuePair<Tuple<int, int>, double> entry in savedValues)
{
values.Add(new XYValues { x = entry.Key.Item1, y = entry.Key.Item2, value = entry.Value });
}
return Results.Ok(values);
});
app.MapPost("/deleteSavedValuesBelow/{hash}", async (String hash) =>
{
try {
Console.WriteLine("Received deleteSavedValuesBelow-call with params: " + hash );
var retVal = await NodeBehavior.DeleteSavedValuesBelow(hash, this);
return Results.Ok(retVal);
} catch (Exception e) {
return Results.BadRequest(e.Message);
}
});




}


//This expects the response to be in exact format
private void DealWithResponse(HttpResponseMessage response){
String responseString = response.Content.ReadAsStringAsync().Result;
Console.WriteLine("Received response from coordinator service: " + responseString);
Expand All @@ -127,7 +152,15 @@ private void DealWithResponse(HttpResponseMessage response){
Console.WriteLine("Received invalid response from coordinator service: " + responseString);
throw new Exception("Received invalid response from coordinator service: " + responseString);
}
//This is an example response: {"HANDLE":{"positions":[{"x":0,"y":0,"value":0.6816054984788531},{"x":1,"y":0,"value":0.6952797360508614},{"x":0,"y":1,"value":3.0950656335878035},{"x":1,"y":1,"value":2.0697533239357435}]}}
//This is an example response: {"HANDLE":{"hash_value":8782,"positions":[{"x":0,"y":0,"value":0.6816054984788531},{"x":1,"y":0,"value":0.6952797360508614},{"x":0,"y":1,"value":3.0950656335878035},{"x":1,"y":1,"value":2.0697533239357435}]}}
if (!responseString.Contains("x") || !responseString.Contains("y") || !responseString.Contains("value")){
Console.WriteLine("Received null response from coordinator service ... ");
return;
}
String hashVal = responseString.Split("\"hash_value\":")[1].Split(",")[0];
UInt16 hash = UInt16.Parse(hashVal);
this.ownerHash = hash;
Console.WriteLine("Set owner hashValue to: " + hash);
String valuesPart = responseString.Split("[{")[1];
String [] valuesStrings = valuesPart.Split("{");
foreach (String valueString in valuesStrings){
Expand All @@ -146,12 +179,36 @@ private void DealWithResponse(HttpResponseMessage response){

}

public class XYValues
public class XYValues
{
public double x { get; set; }
public double y { get; set; }

public double value { get; set; }
}
public class HashedPosition{
public int x { get; set; }
public int y { get; set; }
public ushort hash { get; set; }
}

public class Position{
public int x { get; set; }
public int y { get; set; }
}

[JsonSerializable(typeof(String))]
[JsonSerializable(typeof(List<XYValues>))]
[JsonSerializable(typeof(List<Position>))]
[JsonSerializable(typeof(Position[]))]
[JsonSerializable(typeof(Position))]
[JsonSerializable(typeof(XYValues))]
[JsonSerializable(typeof(XYValues[]))]
[JsonSerializable(typeof(HashedPosition))]
[JsonSerializable(typeof(List<HashedPosition>))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

}
6 changes: 2 additions & 4 deletions Cluster/Node_cs/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@ EXPOSE 5552
ENV ASPNETCORE_URLS=http://+:5552

FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG configuration=Release
WORKDIR /src
COPY ["Node_cs.csproj", "./"]
RUN dotnet restore "Node_cs.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "Node_cs.csproj" -c $configuration -o /app/build
RUN dotnet build "Node_cs.csproj" -c Release -o /app/build

FROM build AS publish
ARG configuration=Release
RUN dotnet publish "Node_cs.csproj" -c $configuration -o /app/publish /p:UseAppHost=false
RUN dotnet publish "Node_cs.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
Expand Down
Loading

0 comments on commit 263fcf9

Please sign in to comment.