client shit

main
Brett 2023-11-18 20:09:49 -05:00
parent 4f7be92b03
commit a3e7245b82
18 changed files with 170 additions and 45 deletions

View File

@ -1,5 +1,9 @@
package client; package client;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import net.jpountz.xxhash.StreamingXXHash64; import net.jpountz.xxhash.StreamingXXHash64;
import shared.ArrayData; import shared.ArrayData;
import shared.FileUtil; import shared.FileUtil;
@ -16,7 +20,14 @@ public class ChunkedCompressedChecksumFileWriter {
private final int bufferSize; private final int bufferSize;
private final long seed; private final long seed;
public ChunkedCompressedChecksumFileWriter(DataOutputStream networkStreamWriter, DataInputStream fileInputReader, int bufferSize, long seed){ private Span currentSpan = null;
private Scope currentScope = null;
private long count = 0;
private long uncompressed_bytes = 0;
private long compressed_bytes = 0;
public ChunkedCompressedChecksumFileWriter(DataOutputStream networkStreamWriter, DataInputStream fileInputReader, int bufferSize, long seed) {
this.networkStreamWriter = networkStreamWriter; this.networkStreamWriter = networkStreamWriter;
this.streamHash = FileUtil.XX_HASH_FACTORY.newStreamingHash64(seed); this.streamHash = FileUtil.XX_HASH_FACTORY.newStreamingHash64(seed);
this.fileInputReader = fileInputReader; this.fileInputReader = fileInputReader;
@ -24,19 +35,45 @@ public class ChunkedCompressedChecksumFileWriter {
this.seed = seed; this.seed = seed;
} }
public void processChunk() throws IOException { public void processChunk(Tracer trace) throws IOException {
if (++count >= FileUtil.MAX_COUNT) {
currentSpan.addEvent("--{End Write}--");
currentSpan.setStatus(StatusCode.OK);
currentScope.close();
currentSpan.end();
currentSpan = null;
currentScope = null;
count = 0;
}
if (currentSpan == null) {
currentSpan = trace.spanBuilder("Chunk Write").startSpan();
currentScope = currentSpan.makeCurrent();
}
// read / write files in chunks // read / write files in chunks
currentSpan.addEvent("--{Begin Write}--");
byte[] uncompressed = readSome(); byte[] uncompressed = readSome();
if (uncompressed.length == 0) if (uncompressed.length == 0)
return; return;
// create a checksum for this chunk + update the overall checksum // create a checksum for this chunk + update the overall checksum
currentSpan.addEvent("Hash");
long hash = hash(uncompressed); long hash = hash(uncompressed);
// apply compression // apply compression
currentSpan.addEvent("Compress");
ArrayData compressed = compress(uncompressed); ArrayData compressed = compress(uncompressed);
// track data
currentSpan.addEvent("Attribute: Write Uncompressed = " + uncompressed.length);
currentSpan.addEvent("Attribute: Write Compressed = " + compressed.getActualLength());
currentSpan.addEvent("Attribute: Compression Ratio = " + ((double)uncompressed.length / (double)compressed.getActualLength()));
currentSpan.addEvent("Attribute: Write Hash = " + hash);
uncompressed_bytes += uncompressed.length;
compressed_bytes += compressed.getActualLength();
count++;
// write data // write data
currentSpan.addEvent("Write");
writeHeader(uncompressed.length, compressed.getActualLength(), hash); writeHeader(uncompressed.length, compressed.getActualLength(), hash);
networkStreamWriter.write(compressed.getData(), 0, compressed.getActualLength()); networkStreamWriter.write(compressed.getData(), 0, compressed.getActualLength());
networkStreamWriter.flush(); networkStreamWriter.flush();
@ -46,6 +83,11 @@ public class ChunkedCompressedChecksumFileWriter {
networkStreamWriter.writeInt(0); networkStreamWriter.writeInt(0);
networkStreamWriter.writeLong(streamHash.getValue()); networkStreamWriter.writeLong(streamHash.getValue());
networkStreamWriter.flush(); networkStreamWriter.flush();
if (currentSpan != null) {
currentSpan.addEvent("--{End Read}--");
currentScope.close();
currentSpan.end();
}
} }
private void writeHeader(int uncompressed, int compressed, long hash) throws IOException { private void writeHeader(int uncompressed, int compressed, long hash) throws IOException {
@ -58,21 +100,35 @@ public class ChunkedCompressedChecksumFileWriter {
byte[] readBytes = new byte[Integer.min(fileInputReader.available(), bufferSize)]; byte[] readBytes = new byte[Integer.min(fileInputReader.available(), bufferSize)];
int totalRead = fileInputReader.read(readBytes); int totalRead = fileInputReader.read(readBytes);
assert(readBytes.length == totalRead); assert (readBytes.length == totalRead);
return readBytes; return readBytes;
} }
private long hash(byte[] input){ private long hash(byte[] input) {
streamHash.update(input, 0, input.length); streamHash.update(input, 0, input.length);
return FileUtil.HASH_64.hash(input, 0, input.length, seed); return FileUtil.HASH_64.hash(input, 0, input.length, seed);
} }
private ArrayData compress(byte[] input){ private ArrayData compress(byte[] input) {
int maxCompressedLength = FileUtil.COMPRESSOR.maxCompressedLength(input.length); int maxCompressedLength = FileUtil.COMPRESSOR.maxCompressedLength(input.length);
byte[] compressedBytes = new byte[maxCompressedLength]; byte[] compressedBytes = new byte[maxCompressedLength];
int compressedLength = FileUtil.COMPRESSOR.compress(input, 0, input.length, compressedBytes, 0, maxCompressedLength); int compressedLength = FileUtil.COMPRESSOR.compress(input, 0, input.length, compressedBytes, 0, maxCompressedLength);
return new ArrayData(compressedBytes, compressedLength); return new ArrayData(compressedBytes, compressedLength);
} }
public long getCompressedBytes() {
return compressed_bytes;
}
public long getUncompressedBytes() {
return uncompressed_bytes;
}
public double getRatio() {
if (compressed_bytes == 0)
return 0;
return (double) uncompressed_bytes / (double) compressed_bytes;
}
} }

View File

@ -1,8 +1,14 @@
package client; package client;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import server.Server; import server.Server;
import shared.ExceptionLogger; import shared.ExceptionLogger;
import shared.FileUtil; import shared.FileUtil;
import shared.OTelUtils;
import java.io.*; import java.io.*;
import java.net.Socket; import java.net.Socket;
@ -13,50 +19,84 @@ public class Client {
private final Socket serverConnection; private final Socket serverConnection;
private final DataOutputStream out; private final DataOutputStream out;
private final DataInputStream in; private final DataInputStream in;
private OTelUtils.SexyContainer ot = OTelUtils.create("CumClient"); // Computational Unit Machine Client
private final Tracer tracer;
private final Scope sc;
private final Span s;
public Client(String address, int port) throws IOException { public Client(String address, int port) throws IOException {
serverConnection = new Socket(address, port); serverConnection = new Socket(address, port);
out = new DataOutputStream(new BufferedOutputStream(serverConnection.getOutputStream())); out = new DataOutputStream(new BufferedOutputStream(serverConnection.getOutputStream()));
in = new DataInputStream(new BufferedInputStream(serverConnection.getInputStream())); in = new DataInputStream(new BufferedInputStream(serverConnection.getInputStream()));
tracer = ot.ot.getTracer("A Client", "1.33.7");
s = tracer.spanBuilder("Client Connection").setAttribute("Server Address", address).setAttribute("Server Port", port).startSpan();
sc = s.makeCurrent();
} }
public Client sendFile(String path){ public Client sendFile(String path) {
Span sp = tracer.spanBuilder("Send File").setAttribute("File", path).startSpan();
try (Scope seethe = sp.makeCurrent()) {
System.out.println("Sending path " + path); System.out.println("Sending path " + path);
FileUtil.write(path, out); FileUtil.write(path, out, tracer, sp);
System.out.println("Sent path " + path);
} finally {
sp.end();
}
ot.tp.forceFlush();
ot.bp.forceFlush();
ot.ox.flush();
return this; return this;
} }
public Client sendDir(String path){ public Client sendDir(String path) {
Span sd = tracer.spanBuilder("Send Directory").setAttribute("Directory", path).startSpan();
try (Scope cope = sd.makeCurrent()) {
File p = new File(path); File p = new File(path);
ArrayDeque<File> filesToCheck = new ArrayDeque<>(Arrays.asList(Objects.requireNonNull(p.listFiles()))); ArrayDeque<File> filesToCheck = new ArrayDeque<>(Arrays.asList(Objects.requireNonNull(p.listFiles())));
while (!filesToCheck.isEmpty()) { while (!filesToCheck.isEmpty()) {
File f = filesToCheck.remove(); File f = filesToCheck.remove();
if (f.isDirectory()){ System.out.println("Processing file " + f.getPath());
filesToCheck.add(f); if (f.isDirectory())
} else filesToCheck.addAll(Arrays.asList(Objects.requireNonNull(f.listFiles())));
else
sendFile(f.getPath()); sendFile(f.getPath());
} }
} finally {
sd.setStatus(StatusCode.OK);
sd.end();
}
System.out.println("Sent directory " + path);
return this; return this;
} }
public void close(){ public Client close() {
try { try {
sc.close();
s.setStatus(StatusCode.OK);
s.end();
out.writeByte(FileUtil.COMMAND.CLOSE.type); out.writeByte(FileUtil.COMMAND.CLOSE.type);
out.flush(); out.flush();
in.close(); in.close();
out.close(); out.close();
serverConnection.close(); serverConnection.close();
} catch (Exception e){ } catch (Exception e) {
ExceptionLogger.log(e); ExceptionLogger.log(e);
} }
System.out.println("Disconnected!"); System.out.println("Disconnected!");
return this;
}
public OTelUtils.SexyContainer getContainer() {
return ot;
} }
public static void main(String[] args) { public static void main(String[] args) {
try { try {
new Client("localhost", Server.SERVER_PORT).sendDir("in/").close(); OTelUtils.SexyContainer con = new Client("localhost", Server.SERVER_PORT).sendDir("in/").close().getContainer();
con.tp.forceFlush();
con.tp.shutdown();
//new Client("localhost", Server.SERVER_PORT).sendFile("in/ihaveafile.txt").close(); //new Client("localhost", Server.SERVER_PORT).sendFile("in/ihaveafile.txt").close();
} catch (Exception e){ } catch (Exception e) {
ExceptionLogger.log(e); ExceptionLogger.log(e);
} }
} }

View File

@ -1,6 +1,7 @@
package server; package server;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import net.jpountz.xxhash.StreamingXXHash64; import net.jpountz.xxhash.StreamingXXHash64;
@ -19,9 +20,8 @@ public class ChunkedCompressedChecksumFileReader {
private Span currentSpan = null; private Span currentSpan = null;
private Scope currentScope = null; private Scope currentScope = null;
private long count = 0;
private static final long MAX_COUNT = 50;
private long count = 0;
private long uncompressed_bytes = 0; private long uncompressed_bytes = 0;
private long compressed_bytes = 0; private long compressed_bytes = 0;
@ -32,16 +32,17 @@ public class ChunkedCompressedChecksumFileReader {
this.seed = seed; this.seed = seed;
} }
public FileHeader readChunk(Tracer trace, Span sp) throws IOException { public FileHeader readChunk(Tracer trace) throws IOException {
if (++count >= MAX_COUNT) { if (++count >= FileUtil.MAX_COUNT) {
currentSpan.addEvent("--{End Read}--"); currentSpan.addEvent("--{End Read}--");
currentSpan.setStatus(StatusCode.OK);
currentScope.close(); currentScope.close();
currentSpan.end(); currentSpan.end();
currentSpan = null; currentSpan = null;
currentScope = null; currentScope = null;
count = 0;
} }
if (currentSpan == null) { if (currentSpan == null) {
count = 0;
currentSpan = trace.spanBuilder("Chunk Read").startSpan(); currentSpan = trace.spanBuilder("Chunk Read").startSpan();
currentScope = currentSpan.makeCurrent(); currentScope = currentSpan.makeCurrent();
} }
@ -72,10 +73,12 @@ public class ChunkedCompressedChecksumFileReader {
throw new RuntimeException("Stream total hash doesn't match the client's sent hash!"); throw new RuntimeException("Stream total hash doesn't match the client's sent hash!");
fileOutputWriter.flush(); fileOutputWriter.flush();
fileOutputWriter.close(); fileOutputWriter.close();
if (currentSpan != null) {
currentSpan.addEvent("--{End Read}--"); currentSpan.addEvent("--{End Read}--");
currentScope.close(); currentScope.close();
currentSpan.end(); currentSpan.end();
} }
}
public long getCompressedBytes(){ public long getCompressedBytes(){
return compressed_bytes; return compressed_bytes;
@ -86,6 +89,8 @@ public class ChunkedCompressedChecksumFileReader {
} }
public double getRatio(){ public double getRatio(){
if (compressed_bytes == 0)
return 0;
return (double) uncompressed_bytes / (double) compressed_bytes; return (double) uncompressed_bytes / (double) compressed_bytes;
} }

View File

@ -3,6 +3,7 @@ package server;
import client.Client; import client.Client;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
@ -73,6 +74,7 @@ public class Connection implements Runnable {
} }
} }
} finally { } finally {
fileSend.setStatus(StatusCode.OK);
fileSend.end(); fileSend.end();
} }
try { try {

View File

@ -24,10 +24,10 @@ public class Server {
public static volatile boolean running = true; public static volatile boolean running = true;
private static final OpenTelemetry ot = OTelUtils.create("CumServer"); private static final OTelUtils.SexyContainer ot = OTelUtils.create("CumServer");
public Server() { public Server() {
Tracer main = ot.getTracer("Main Server", "0.69"); Tracer main = ot.ot.getTracer("Main Server", "0.69");
try { try {
System.out.println("Starting server"); System.out.println("Starting server");
ServerSocket serverSocket = new ServerSocket(SERVER_PORT); ServerSocket serverSocket = new ServerSocket(SERVER_PORT);

View File

@ -2,6 +2,7 @@ package shared;
import client.ChunkedCompressedChecksumFileWriter; import client.ChunkedCompressedChecksumFileWriter;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import net.jpountz.lz4.LZ4Compressor; import net.jpountz.lz4.LZ4Compressor;
@ -21,6 +22,7 @@ public class FileUtil {
// do not change it breaks stuff // do not change it breaks stuff
protected static final int READER_SIZE = 65000; protected static final int READER_SIZE = 65000;
public static final long SEED = 691; public static final long SEED = 691;
public static final long MAX_COUNT = 128;
private static final LZ4Factory LZ_FACTORY = LZ4Factory.fastestInstance(); private static final LZ4Factory LZ_FACTORY = LZ4Factory.fastestInstance();
public static final LZ4Compressor COMPRESSOR = LZ_FACTORY.highCompressor(); public static final LZ4Compressor COMPRESSOR = LZ_FACTORY.highCompressor();
@ -39,7 +41,7 @@ public class FileUtil {
} }
} }
public static void write(String path, DataOutputStream dataOut) { public static void write(String path, DataOutputStream dataOut, Tracer trace, Span sp) {
validatePath(path); validatePath(path);
String relative_path = path.replace(System.getProperty("user.dir"), ""); String relative_path = path.replace(System.getProperty("user.dir"), "");
try { try {
@ -51,7 +53,12 @@ public class FileUtil {
ChunkedCompressedChecksumFileWriter writer = new ChunkedCompressedChecksumFileWriter(dataOut, fileReader, FileUtil.READER_SIZE, FileUtil.SEED); ChunkedCompressedChecksumFileWriter writer = new ChunkedCompressedChecksumFileWriter(dataOut, fileReader, FileUtil.READER_SIZE, FileUtil.SEED);
while (fileReader.available() > 0) while (fileReader.available() > 0)
writer.processChunk(); writer.processChunk(trace);
sp.setAttribute("Data Read Uncompressed Bytes", writer.getUncompressedBytes());
sp.setAttribute("Data Read Compressed Bytes", writer.getCompressedBytes());
sp.setAttribute("Data Compression Ratio", writer.getRatio());
sp.setStatus(StatusCode.OK);
writer.close(); writer.close();
fileReader.close(); fileReader.close();
@ -72,7 +79,7 @@ public class FileUtil {
// ugh I want while(reader.readChunk().getUncompressed()); but it makes warnings!!! // ugh I want while(reader.readChunk().getUncompressed()); but it makes warnings!!!
while (true) { while (true) {
if (reader.readChunk(trace, sp).getUncompressed() == 0) { if (reader.readChunk(trace).getUncompressed() == 0) {
sp.addEvent("Chunk Read"); sp.addEvent("Chunk Read");
break; break;
} }
@ -80,6 +87,7 @@ public class FileUtil {
sp.setAttribute("Data Read Uncompressed Bytes", reader.getUncompressedBytes()); sp.setAttribute("Data Read Uncompressed Bytes", reader.getUncompressedBytes());
sp.setAttribute("Data Read Compressed Bytes", reader.getCompressedBytes()); sp.setAttribute("Data Read Compressed Bytes", reader.getCompressedBytes());
sp.setAttribute("Data Compression Ratio", reader.getRatio()); sp.setAttribute("Data Compression Ratio", reader.getRatio());
sp.setStatus(StatusCode.OK);
reader.close(); reader.close();
System.out.println("Writing " + path + " complete"); System.out.println("Writing " + path + " complete");
sp.addEvent("File Written"); sp.addEvent("File Written");

View File

@ -23,6 +23,19 @@ import io.opentelemetry.semconv.ResourceAttributes;
public class OTelUtils { public class OTelUtils {
public static class SexyContainer {
public OpenTelemetry ot;
public SdkTracerProvider tp;
public BatchSpanProcessor bp;
public SpanExporter ox;
public SexyContainer(OpenTelemetry ot, SdkTracerProvider tp, BatchSpanProcessor bp, SpanExporter ox){
this.ot = ot;
this.tp = tp;
this.bp = bp;
this.ox = ox;
}
}
public static OpenTelemetry createLogger(){ public static OpenTelemetry createLogger(){
Resource resource = Resource.getDefault().toBuilder().put(ResourceAttributes.SERVICE_NAME, "cum").put(ResourceAttributes.SERVICE_VERSION, "0.1.0").build(); Resource resource = Resource.getDefault().toBuilder().put(ResourceAttributes.SERVICE_NAME, "cum").put(ResourceAttributes.SERVICE_VERSION, "0.1.0").build();
@ -39,7 +52,7 @@ public class OTelUtils {
.buildAndRegisterGlobal(); .buildAndRegisterGlobal();
} }
public static OpenTelemetry create(String name){ public static SexyContainer create(String name){
Resource resource = Resource.getDefault().toBuilder().put(ResourceAttributes.SERVICE_NAME.getKey(), name).put(ResourceAttributes.SERVICE_VERSION.getKey(), "1.3.37").build(); Resource resource = Resource.getDefault().toBuilder().put(ResourceAttributes.SERVICE_NAME.getKey(), name).put(ResourceAttributes.SERVICE_VERSION.getKey(), "1.3.37").build();
SpanExporter otlpExporter = OtlpGrpcSpanExporter.builder() SpanExporter otlpExporter = OtlpGrpcSpanExporter.builder()
@ -57,12 +70,12 @@ public class OTelUtils {
.setResource(resource) .setResource(resource)
.build(); .build();
return OpenTelemetrySdk.builder() return new SexyContainer(OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider) .setTracerProvider(sdkTracerProvider)
.setMeterProvider(createLoggingMeter(resource)) .setMeterProvider(createLoggingMeter(resource))
.setLoggerProvider(createLoggerProvider(resource)) .setLoggerProvider(createLoggerProvider(resource))
.setPropagators(ContextPropagators.create(TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance()))) .setPropagators(ContextPropagators.create(TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance())))
.buildAndRegisterGlobal(); .buildAndRegisterGlobal(), sdkTracerProvider, batchSpanProcessor, otlpExporter);
} }
private static SdkMeterProvider createLoggingMeter(Resource resource){ private static SdkMeterProvider createLoggingMeter(Resource resource){

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,12 +1,13 @@
shared/ExceptionLogger.class shared/ExceptionLogger.class
shared/FileUtil$InvalidUsageException.class shared/OTelUtils$SexyContainer.class
shared/FileUtil.class shared/FileUtil.class
shared/OTelUtils.class
client/Client.class
server/Server.class server/Server.class
server/Connection.class server/Connection.class
server/FileHeader.class
shared/FileUtil$COMMAND.class
shared/ArrayData.class shared/ArrayData.class
server/ChunkedCompressedChecksumFileReader.class server/ChunkedCompressedChecksumFileReader.class
client/ChunkedCompressedChecksumFileWriter.class client/ChunkedCompressedChecksumFileWriter.class
shared/FileUtil$InvalidUsageException.class
shared/OTelUtils.class
client/Client.class
server/FileHeader.class
shared/FileUtil$COMMAND.class