Skip to content
Snippets Groups Projects
Commit e483e82f authored by Ivan Pavlovich's avatar Ivan Pavlovich
Browse files

Mierda

parent 89b396c0
No related branches found
No related tags found
No related merge requests found
Showing
with 503 additions and 0 deletions
/target
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/async_runtime/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/client/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/data_layer/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/server/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/RUST-Async-Server.iml" filepath="$PROJECT_DIR$/.idea/RUST-Async-Server.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "RUST"
version = "0.1.0"
[[package]]
name = "async_runtime"
version = "0.1.0"
[[package]]
name = "client"
version = "0.1.0"
dependencies = [
"async_runtime",
"data_layer",
]
[[package]]
name = "data_layer"
version = "0.1.0"
[[package]]
name = "server"
version = "0.1.0"
dependencies = [
"async_runtime",
"data_layer",
]
[package]
name = "RUST"
version = "0.1.0"
edition = "2024"
[dependencies]
[workspace]
members = [
"client",
"server",
"async_runtime",
"data_layer"
]
[package]
name = "async_runtime"
version = "0.1.0"
edition = "2024"
[dependencies]
use std::{
future::Future,
sync::{Arc, mpsc},
task::{Context, Poll, Waker},
pin::Pin,
collections::VecDeque
};
use crate::waker::create_raw_waker;
pub struct Task {
future: Pin<Box<dyn Future<Output = ()> + Send>>,
waker: Arc<Waker>,
}
pub struct Executor {
pub polling: VecDeque<Task>,
}
impl Executor {
pub fn new() -> Self {
Executor {
polling: VecDeque::new(),
}
}
pub fn spawn<F, T>(&mut self, future: F) -> mpsc::Receiver<T>
where
F: Future<Output = T> + 'static + Send,
T: Send + 'static,
{
let (tx, rx) = mpsc::channel();
let future: Pin<Box<dyn Future<Output = ()> + Send>> = Box::pin(
async move {
let result = future.await;
let _ = tx.send(result);
}
);
let task = Task {
future,
waker: self.create_waker(),
};
self.polling.push_back(task);
rx
}
pub fn poll(&mut self) {
let mut task = match self.polling.pop_front() {
Some(task) => task,
None => return,
};
let waker = task.waker.clone();
let context = &mut Context::from_waker(&waker);
match task.future.as_mut().poll(context) {
Poll::Ready(()) => {
// println!("Task ready!")
}
Poll::Pending => {
// println!("Task pending!");
self.polling.push_back(task);
}
}
}
pub fn create_waker(&self) -> Arc<Waker> {
Arc::new(unsafe{Waker::from_raw(create_raw_waker())})
}
}
\ No newline at end of file
pub mod executor;
pub mod waker;
pub mod reciever;
pub mod sleep;
pub mod sender;
\ No newline at end of file
use std::{
future::Future,
task::{Context, Poll},
pin::Pin
};
mod executor;
mod waker;
mod sender;
mod reciever;
mod sleep;
pub struct CountingFuture {
pub count: i32,
}
impl Future for CountingFuture {
type Output = i32;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.count += 1;
if self.count == 4 {
println!("CountingFuture is done!");
Poll::Ready(self.count)
} else {
cx.waker().wake_by_ref();
println!("CountingFuture is not done yet! {}", self.count);
Poll::Pending
}
}
}
fn main() {
let counter = CountingFuture { count: 0 };
let counter_two = CountingFuture { count: 0 };
let mut executor = executor::Executor::new();
let handle = executor.spawn(counter);
let _handle_two = executor.spawn(counter_two);
std::thread::spawn(move || {
loop {
executor.poll();
}
});
let result = handle.recv().unwrap();
println!("Result: {}", result);
}
\ No newline at end of file
use std::{
future::Future,
task::{Context, Poll},
pin::Pin,
net::TcpStream,
io::{self, Read},
sync::{Arc, Mutex}
};
pub struct TcpReceiver {
pub stream: Arc<Mutex<TcpStream>>,
pub buffer: Vec<u8>
}
impl Future for TcpReceiver {
type Output = io::Result<Vec<u8>>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut stream = match self.stream.try_lock() {
Ok(stream) => stream,
Err(_) => {
cx.waker().wake_by_ref();
return Poll::Pending;
}
};
stream.set_nonblocking(true)?;
let mut local_buf = [0; 1024];
match stream.read(&mut local_buf) {
Ok(0) => {
Poll::Ready(Ok(self.buffer.to_vec()))
},
Ok(n) => {
std::mem::drop(stream);
self.buffer.extend_from_slice(&local_buf[..n]);
cx.waker().wake_by_ref();
Poll::Pending
},
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
cx.waker().wake_by_ref();
Poll::Pending
},
Err(e) => Poll::Ready(Err(e))
}
}
}
\ No newline at end of file
use std::{
future::Future,
task::{Context, Poll},
pin::Pin,
net::TcpStream,
io::{self, Write},
sync::{Arc, Mutex}
};
pub struct TcpSender {
pub stream: Arc<Mutex<TcpStream>>,
pub buffer: Vec<u8>
}
impl Future for TcpSender {
type Output = io::Result<()>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut stream = match self.stream.try_lock() {
Ok(stream) => stream,
Err(_) => {
cx.waker().wake_by_ref();
return Poll::Pending;
}
};
stream.set_nonblocking(true)?;
match stream.write_all(&self.buffer) {
Ok(_) => {
Poll::Ready(Ok(()))
},
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
cx.waker().wake_by_ref();
Poll::Pending
},
Err(e) => Poll::Ready(Err(e))
}
}
}
\ No newline at end of file
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
time::{Duration, Instant},
};
pub struct Sleep {
when: Instant,
}
impl Sleep {
pub fn new(duration: Duration) -> Self {
Sleep {
when: Instant::now() + duration,
}
}
}
impl Future for Sleep {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>)
-> Poll<Self::Output> {
let now = Instant::now();
if now >= self.when {
Poll::Ready(())
} else {
cx.waker().wake_by_ref();
Poll::Pending
}
}
}
\ No newline at end of file
use std::task::{RawWaker, RawWakerVTable};
static VTABLE: RawWakerVTable = RawWakerVTable::new(
my_clone,
my_wake,
my_wake_by_ref,
my_drop,
);
unsafe fn my_clone(raw_waker: *const ()) -> RawWaker {
RawWaker::new(raw_waker, &VTABLE)
}
unsafe fn my_wake(raw_waker: *const ()) {
drop(Box::from_raw(raw_waker as *mut u32));
}
unsafe fn my_wake_by_ref(_raw_waker: *const ()) {
}
unsafe fn my_drop(raw_waker: *const ()) {
drop(Box::from_raw(raw_waker as *mut u32));
}
pub fn create_raw_waker() -> RawWaker {
let data = Box::into_raw(Box::new(42u32));
RawWaker::new(data as *const (), &VTABLE)
}
\ No newline at end of file
[package]
name = "client"
version = "0.1.0"
edition = "2024"
[dependencies]
data_layer = { path = "../data_layer" }
async_runtime = { path = "../async_runtime" }
use std::{
io,
sync::{Arc, Mutex},
net::TcpStream,
time::Instant
};
use data_layer::data::Data;
use async_runtime::{
executor::Executor,
reciever::TcpReceiver,
sender::TcpSender,
};
async fn send_data(field1: u32, field2: u16, field3: String)
-> io::Result<String> {
let stream = Arc::new(Mutex::new(TcpStream::connect(
"127.0.0.1:7878")?
));
let message = Data {field1, field2, field3};
TcpSender {
stream: stream.clone(),
buffer: message.serialize()?
}.await?;
let receiver = TcpReceiver {
stream: stream.clone(),
buffer: Vec::new()
};
String::from_utf8(receiver.await?).map_err(|_|
io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8")
)
}
fn main() -> io::Result<()> {
let mut executor = Executor::new();
let mut handles = Vec::new();
let start = Instant::now();
for i in 0..10 {
let handle = executor.spawn(send_data(
i, i as u16, format!("Hello, server! {}", i)
));
handles.push(handle);
}
std::thread::spawn(move || {
loop {
executor.poll();
}
});
println!("Waiting for result...");
for handle in handles {
match handle.recv().unwrap() {
Ok(result) => println!("Result: {}", result),
Err(e) => println!("Error: {}", e)
//Err(e) => ()
};
}
let duration = start.elapsed();
println!("Time elapsed in expensive_function() is: {:?}", duration);
Ok(())
}
\ No newline at end of file
[package]
name = "data_layer"
version = "0.1.0"
edition = "2024"
[dependencies]
use std::io::{self, Cursor, Read, Write};
#[derive(Debug)]
pub struct Data {
pub field1: u32,
pub field2: u16,
pub field3: String,
}
impl Data {
pub fn serialize(&self) -> io::Result<Vec<u8>> {
let mut bytes = Vec::new();
bytes.write(&self.field1.to_ne_bytes())?;
bytes.write(&self.field2.to_ne_bytes())?;
let field3_len = self.field3.len() as u32;
bytes.write(&field3_len.to_ne_bytes())?;
bytes.extend_from_slice(self.field3.as_bytes());
Ok(bytes)
}
pub fn deserialize(cursor: &mut Cursor<&[u8]>) -> io::Result<Data> {
// Initialize buffers for the fields, using arrays of the appropriate size
let mut field1_bytes = [0u8; 4];
let mut field2_bytes = [0u8; 2];
// Read the first field (4 bytes) from the cursor into the buffer.
// Do the same for second field.
cursor.read_exact(&mut field1_bytes)?;
cursor.read_exact(&mut field2_bytes)?;
// Convert the byte arrays into the appropriate data types (u32 and u16)
let field1 = u32::from_ne_bytes(field1_bytes);
let field2 = u16::from_ne_bytes(field2_bytes);
// Initialize a buffer to read the length of the third field,
// which is 4 bytes long
let mut len_bytes = [0u8; 4];
// Read the length from the cursor into the buffer
cursor.read_exact(&mut len_bytes)?;
// Convert the length bytes into a usize
let len = u32::from_ne_bytes(len_bytes) as usize;
// Initialize a buffer with the specified length to hold the third field's data
let mut field3_bytes = vec![0u8; len];
// Read the third field's data from the cursor into the buffer
cursor.read_exact(&mut field3_bytes)?;
// Convert the third field's bytes into a UTF-8 string, or
// return an error if this cannot be done.
let field3 = String::from_utf8(field3_bytes)
.map_err(|_| io::Error::new(
io::ErrorKind::InvalidData, "Invalid UTF-8"
))?;
// Return the structured data
Ok(Data { field1, field2, field3 })
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment