mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Fix network event update Message (#37543)
- Add `ResourceArrayType` with `Available` and `Updated` variants - Rename `resources-available` and `resource-available` to `resources-array` ,`resource-array` - Add `ResourceArrayType` as an argument to decide the type of resources - Add `Option<ResponseContentMsg>`,`Option<ResponseStartMsg>`, `Option<ResponseCookiesMsg>`, `Option<ResponseHeadersMsg>`,`Option<RequestCookiesMsg>`, `Option<RequestHeadersMsg>`, `total_time`, `security_state` to `NetworkEventActor` struct , and serialize the data in each to `resource_updates` , flattening the nested arrays into a single JSON - Refactor the following methods `request_headers`,`response_start` , `response_content`,`response_cookies`,`response_headers`, `request_cookies`,`total_time` to associated functions passing `HttpRequest` and `HttpResponse` as parameters . Testing: Ran servo with devtools flag to see the logs corresponding to the changes Fixes: https://github.com/servo/servo/issues/37479 This PR Builds on https://github.com/servo/servo/pull/37517 and was opened due to merge conflicts and branch issues --------- Signed-off-by: Uthman Yahaya Baba <uthmanyahayababa@gmail.com>
This commit is contained in:
parent
8edae71286
commit
7d2c9ec19c
6 changed files with 216 additions and 138 deletions
|
@ -30,7 +30,7 @@ use crate::actors::browsing_context::BrowsingContextActor;
|
|||
use crate::actors::object::ObjectActor;
|
||||
use crate::actors::worker::WorkerActor;
|
||||
use crate::protocol::JsonPacketStream;
|
||||
use crate::resource::ResourceAvailable;
|
||||
use crate::resource::{ResourceArrayType, ResourceAvailable};
|
||||
use crate::{StreamId, UniqueId};
|
||||
|
||||
trait EncodableConsoleMessage {
|
||||
|
@ -261,13 +261,12 @@ impl ConsoleActor {
|
|||
.push(CachedConsoleMessage::PageError(page_error.clone()));
|
||||
if id == self.current_unique_id(registry) {
|
||||
if let Root::BrowsingContext(bc) = &self.root {
|
||||
registry
|
||||
.find::<BrowsingContextActor>(bc)
|
||||
.resource_available(
|
||||
PageErrorWrapper { page_error },
|
||||
"error-message".into(),
|
||||
stream,
|
||||
)
|
||||
registry.find::<BrowsingContextActor>(bc).resource_array(
|
||||
PageErrorWrapper { page_error },
|
||||
"error-message".into(),
|
||||
ResourceArrayType::Available,
|
||||
stream,
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -287,9 +286,12 @@ impl ConsoleActor {
|
|||
.push(CachedConsoleMessage::ConsoleLog(log_message.clone()));
|
||||
if id == self.current_unique_id(registry) {
|
||||
if let Root::BrowsingContext(bc) = &self.root {
|
||||
registry
|
||||
.find::<BrowsingContextActor>(bc)
|
||||
.resource_available(log_message, "console-message".into(), stream)
|
||||
registry.find::<BrowsingContextActor>(bc).resource_array(
|
||||
log_message,
|
||||
"console-message".into(),
|
||||
ResourceArrayType::Available,
|
||||
stream,
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@ use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
|
|||
use crate::network_handler::Cause;
|
||||
use crate::protocol::JsonPacketStream;
|
||||
|
||||
struct HttpRequest {
|
||||
#[derive(Clone)]
|
||||
pub struct HttpRequest {
|
||||
url: String,
|
||||
method: Method,
|
||||
headers: HeaderMap,
|
||||
|
@ -32,7 +33,8 @@ struct HttpRequest {
|
|||
send_time: Duration,
|
||||
}
|
||||
|
||||
struct HttpResponse {
|
||||
#[derive(Clone)]
|
||||
pub struct HttpResponse {
|
||||
headers: Option<HeaderMap>,
|
||||
status: HttpStatus,
|
||||
body: Option<Vec<u8>>,
|
||||
|
@ -40,9 +42,27 @@ struct HttpResponse {
|
|||
|
||||
pub struct NetworkEventActor {
|
||||
pub name: String,
|
||||
request: HttpRequest,
|
||||
response: HttpResponse,
|
||||
is_xhr: bool,
|
||||
pub request: HttpRequest,
|
||||
pub response: HttpResponse,
|
||||
pub is_xhr: bool,
|
||||
pub response_content: Option<ResponseContentMsg>,
|
||||
pub response_start: Option<ResponseStartMsg>,
|
||||
pub response_cookies: Option<ResponseCookiesMsg>,
|
||||
pub response_headers: Option<ResponseHeadersMsg>,
|
||||
pub request_cookies: Option<RequestCookiesMsg>,
|
||||
pub request_headers: Option<RequestHeadersMsg>,
|
||||
pub total_time: Duration,
|
||||
pub security_state: String,
|
||||
pub event_timing: Option<Timings>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NetworkEventResource {
|
||||
pub resource_id: u64,
|
||||
pub resource_updates: Map<String, Value>,
|
||||
pub browsing_context_id: u64,
|
||||
pub inner_window_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
|
@ -157,7 +177,7 @@ struct GetResponseCookiesReply {
|
|||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Timings {
|
||||
pub struct Timings {
|
||||
blocked: u32,
|
||||
dns: u32,
|
||||
connect: u64,
|
||||
|
@ -336,27 +356,39 @@ impl Actor for NetworkEventActor {
|
|||
|
||||
impl NetworkEventActor {
|
||||
pub fn new(name: String) -> NetworkEventActor {
|
||||
let request = HttpRequest {
|
||||
url: String::new(),
|
||||
method: Method::GET,
|
||||
headers: HeaderMap::new(),
|
||||
body: None,
|
||||
started_date_time: SystemTime::now(),
|
||||
time_stamp: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs() as i64,
|
||||
send_time: Duration::ZERO,
|
||||
connect_time: Duration::ZERO,
|
||||
};
|
||||
let response = HttpResponse {
|
||||
headers: None,
|
||||
status: HttpStatus::default(),
|
||||
body: None,
|
||||
};
|
||||
|
||||
NetworkEventActor {
|
||||
name,
|
||||
request: HttpRequest {
|
||||
url: String::new(),
|
||||
method: Method::GET,
|
||||
headers: HeaderMap::new(),
|
||||
body: None,
|
||||
started_date_time: SystemTime::now(),
|
||||
time_stamp: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs() as i64,
|
||||
send_time: Duration::ZERO,
|
||||
connect_time: Duration::ZERO,
|
||||
},
|
||||
response: HttpResponse {
|
||||
headers: None,
|
||||
status: HttpStatus::default(),
|
||||
body: None,
|
||||
},
|
||||
request: request.clone(),
|
||||
response: response.clone(),
|
||||
is_xhr: false,
|
||||
response_content: None,
|
||||
response_start: None,
|
||||
response_cookies: None,
|
||||
response_headers: None,
|
||||
request_cookies: None,
|
||||
request_headers: None,
|
||||
total_time: Self::total_time(&request),
|
||||
security_state: "insecure".to_owned(), // Default security state
|
||||
event_timing: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,12 +449,13 @@ impl NetworkEventActor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn response_start(&self) -> ResponseStartMsg {
|
||||
#[allow(dead_code)]
|
||||
pub fn response_start(response: &HttpResponse) -> ResponseStartMsg {
|
||||
// TODO: Send the correct values for all these fields.
|
||||
let h_size_option = self.response.headers.as_ref().map(|headers| headers.len());
|
||||
let h_size = h_size_option.unwrap_or(0);
|
||||
let status = &self.response.status;
|
||||
// TODO: Send the correct values for remoteAddress and remotePort and http_version.
|
||||
let h_size = response.headers.as_ref().map(|h| h.len()).unwrap_or(0);
|
||||
let status = &response.status;
|
||||
|
||||
// TODO: Send the correct values for remoteAddress and remotePort and http_version
|
||||
ResponseStartMsg {
|
||||
http_version: "HTTP/1.1".to_owned(),
|
||||
remote_address: "63.245.217.43".to_owned(),
|
||||
|
@ -434,26 +467,29 @@ impl NetworkEventActor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn response_content(&self) -> ResponseContentMsg {
|
||||
let mut m_string = "".to_owned();
|
||||
if let Some(ref headers) = self.response.headers {
|
||||
m_string = match headers.typed_get::<ContentType>() {
|
||||
#[allow(dead_code)]
|
||||
pub fn response_content(response: &HttpResponse) -> ResponseContentMsg {
|
||||
let mime_type = if let Some(ref headers) = response.headers {
|
||||
match headers.typed_get::<ContentType>() {
|
||||
Some(ct) => ct.to_string(),
|
||||
_ => "".to_owned(),
|
||||
};
|
||||
}
|
||||
None => "".to_string(),
|
||||
}
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
// TODO: Set correct values when response's body is sent to the devtools in http_loader.
|
||||
ResponseContentMsg {
|
||||
mime_type: m_string,
|
||||
mime_type,
|
||||
content_size: 0,
|
||||
transferred_size: 0,
|
||||
discard_response_body: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn response_cookies(&self) -> ResponseCookiesMsg {
|
||||
#[allow(dead_code)]
|
||||
pub fn response_cookies(response: &HttpResponse) -> ResponseCookiesMsg {
|
||||
let mut cookies_size = 0;
|
||||
if let Some(ref headers) = self.response.headers {
|
||||
if let Some(ref headers) = response.headers {
|
||||
cookies_size = match headers.typed_get::<Cookie>() {
|
||||
Some(ref cookie) => cookie.len(),
|
||||
_ => 0,
|
||||
|
@ -464,10 +500,11 @@ impl NetworkEventActor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn response_headers(&self) -> ResponseHeadersMsg {
|
||||
#[allow(dead_code)]
|
||||
pub fn response_headers(response: &HttpResponse) -> ResponseHeadersMsg {
|
||||
let mut headers_size = 0;
|
||||
let mut headers_byte_count = 0;
|
||||
if let Some(ref headers) = self.response.headers {
|
||||
if let Some(ref headers) = response.headers {
|
||||
headers_size = headers.len();
|
||||
for (name, value) in headers.iter() {
|
||||
headers_byte_count += name.as_str().len() + value.len();
|
||||
|
@ -479,18 +516,20 @@ impl NetworkEventActor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn request_headers(&self) -> RequestHeadersMsg {
|
||||
let size = self.request.headers.iter().fold(0, |acc, (name, value)| {
|
||||
#[allow(dead_code)]
|
||||
pub fn request_headers(request: &HttpRequest) -> RequestHeadersMsg {
|
||||
let size = request.headers.iter().fold(0, |acc, (name, value)| {
|
||||
acc + name.as_str().len() + value.len()
|
||||
});
|
||||
RequestHeadersMsg {
|
||||
headers: self.request.headers.len(),
|
||||
headers: request.headers.len(),
|
||||
headers_size: size,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn request_cookies(&self) -> RequestCookiesMsg {
|
||||
let cookies_size = match self.request.headers.typed_get::<Cookie>() {
|
||||
#[allow(dead_code)]
|
||||
pub fn request_cookies(request: &HttpRequest) -> RequestCookiesMsg {
|
||||
let cookies_size = match request.headers.typed_get::<Cookie>() {
|
||||
Some(ref cookie) => cookie.len(),
|
||||
_ => 0,
|
||||
};
|
||||
|
@ -499,7 +538,78 @@ impl NetworkEventActor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn total_time(&self) -> Duration {
|
||||
self.request.connect_time + self.request.send_time
|
||||
pub fn total_time(request: &HttpRequest) -> Duration {
|
||||
request.connect_time + request.send_time
|
||||
}
|
||||
|
||||
fn insert_serialized_map<T: Serialize>(map: &mut Map<String, Value>, obj: &Option<T>) {
|
||||
if let Some(value) = obj {
|
||||
if let Ok(Value::Object(serialized)) = serde_json::to_value(value) {
|
||||
for (key, val) in serialized {
|
||||
map.insert(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resource_updates(&self) -> NetworkEventResource {
|
||||
let mut resource_updates = Map::new();
|
||||
|
||||
resource_updates.insert(
|
||||
"requestCookiesAvailable".to_owned(),
|
||||
Value::Bool(self.request_cookies.is_some()),
|
||||
);
|
||||
|
||||
resource_updates.insert(
|
||||
"requestHeadersAvailable".to_owned(),
|
||||
Value::Bool(self.request_headers.is_some()),
|
||||
);
|
||||
|
||||
resource_updates.insert(
|
||||
"responseHeadersAvailable".to_owned(),
|
||||
Value::Bool(self.response_headers.is_some()),
|
||||
);
|
||||
resource_updates.insert(
|
||||
"responseCookiesAvailable".to_owned(),
|
||||
Value::Bool(self.response_cookies.is_some()),
|
||||
);
|
||||
resource_updates.insert(
|
||||
"responseStartAvailable".to_owned(),
|
||||
Value::Bool(self.response_start.is_some()),
|
||||
);
|
||||
resource_updates.insert(
|
||||
"responseContentAvailable".to_owned(),
|
||||
Value::Bool(self.response_content.is_some()),
|
||||
);
|
||||
|
||||
resource_updates.insert(
|
||||
"totalTime".to_string(),
|
||||
Value::from(self.total_time.as_secs_f64()),
|
||||
);
|
||||
|
||||
resource_updates.insert(
|
||||
"securityState".to_string(),
|
||||
Value::String(self.security_state.clone()),
|
||||
);
|
||||
resource_updates.insert(
|
||||
"eventTimingsAvailable".to_owned(),
|
||||
Value::Bool(self.event_timing.is_some()),
|
||||
);
|
||||
|
||||
Self::insert_serialized_map(&mut resource_updates, &self.response_content);
|
||||
Self::insert_serialized_map(&mut resource_updates, &self.response_headers);
|
||||
Self::insert_serialized_map(&mut resource_updates, &self.response_cookies);
|
||||
Self::insert_serialized_map(&mut resource_updates, &self.request_headers);
|
||||
Self::insert_serialized_map(&mut resource_updates, &self.request_cookies);
|
||||
Self::insert_serialized_map(&mut resource_updates, &self.response_start);
|
||||
Self::insert_serialized_map(&mut resource_updates, &self.event_timing);
|
||||
|
||||
// TODO: Set the correct values for these fields
|
||||
NetworkEventResource {
|
||||
resource_id: 0,
|
||||
resource_updates,
|
||||
browsing_context_id: 0,
|
||||
inner_window_id: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ use crate::actors::watcher::thread_configuration::{
|
|||
ThreadConfigurationActor, ThreadConfigurationActorMsg,
|
||||
};
|
||||
use crate::protocol::JsonPacketStream;
|
||||
use crate::resource::ResourceAvailable;
|
||||
use crate::resource::{ResourceArrayType, ResourceAvailable};
|
||||
use crate::{EmptyReplyMsg, StreamId, WorkerActor};
|
||||
|
||||
pub mod network_parent;
|
||||
|
@ -292,14 +292,20 @@ impl Actor for WatcherActor {
|
|||
title: Some(target.title.borrow().clone()),
|
||||
url: Some(target.url.borrow().clone()),
|
||||
};
|
||||
target.resource_available(event, "document-event".into(), stream);
|
||||
target.resource_array(
|
||||
event,
|
||||
"document-event".into(),
|
||||
ResourceArrayType::Available,
|
||||
stream,
|
||||
);
|
||||
}
|
||||
},
|
||||
"source" => {
|
||||
let thread_actor = registry.find::<ThreadActor>(&target.thread);
|
||||
target.resources_available(
|
||||
target.resources_array(
|
||||
thread_actor.source_manager.source_forms(registry),
|
||||
"source".into(),
|
||||
ResourceArrayType::Available,
|
||||
stream,
|
||||
);
|
||||
|
||||
|
@ -307,9 +313,10 @@ impl Actor for WatcherActor {
|
|||
let worker = registry.find::<WorkerActor>(worker_name);
|
||||
let thread = registry.find::<ThreadActor>(&worker.thread);
|
||||
|
||||
worker.resources_available(
|
||||
worker.resources_array(
|
||||
thread.source_manager.source_forms(registry),
|
||||
"source".into(),
|
||||
ResourceArrayType::Available,
|
||||
stream,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ use devtools_traits::{
|
|||
use embedder_traits::{AllowOrDeny, EmbedderMsg, EmbedderProxy};
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use log::trace;
|
||||
use resource::ResourceAvailable;
|
||||
use resource::{ResourceArrayType, ResourceAvailable};
|
||||
use serde::Serialize;
|
||||
use servo_rand::RngCore;
|
||||
|
||||
|
@ -540,7 +540,12 @@ impl DevtoolsInstance {
|
|||
let worker_actor = actors.find::<WorkerActor>(worker_actor_name);
|
||||
|
||||
for stream in self.connections.values_mut() {
|
||||
worker_actor.resource_available(&source_form, "source".into(), stream);
|
||||
worker_actor.resource_array(
|
||||
&source_form,
|
||||
"source".into(),
|
||||
ResourceArrayType::Available,
|
||||
stream,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let Some(browsing_context_id) = self.pipelines.get(&pipeline_id) else {
|
||||
|
@ -563,7 +568,12 @@ impl DevtoolsInstance {
|
|||
let browsing_context = actors.find::<BrowsingContextActor>(actor_name);
|
||||
|
||||
for stream in self.connections.values_mut() {
|
||||
browsing_context.resource_available(&source_form, "source".into(), stream);
|
||||
browsing_context.resource_array(
|
||||
&source_form,
|
||||
"source".into(),
|
||||
ResourceArrayType::Available,
|
||||
stream,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,30 +11,8 @@ use serde::Serialize;
|
|||
use crate::actor::ActorRegistry;
|
||||
use crate::actors::browsing_context::BrowsingContextActor;
|
||||
use crate::actors::network_event::NetworkEventActor;
|
||||
use crate::resource::ResourceAvailable;
|
||||
use crate::resource::{ResourceArrayType, ResourceAvailable};
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
struct ResourcesUpdatedArray {
|
||||
updates: Vec<UpdateEntry>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
struct UpdateEntry {
|
||||
#[serde(rename = "updateType")]
|
||||
update_type: String,
|
||||
data: serde_json::Value,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct EventTimingsUpdateMsg {
|
||||
total_time: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct SecurityInfoUpdateMsg {
|
||||
state: String,
|
||||
}
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct Cause {
|
||||
#[serde(rename = "type")]
|
||||
|
@ -63,9 +41,10 @@ pub(crate) fn handle_network_event(
|
|||
let browsing_context_actor =
|
||||
actors.find::<BrowsingContextActor>(&browsing_context_actor_name);
|
||||
for stream in &mut connections {
|
||||
browsing_context_actor.resource_available(
|
||||
browsing_context_actor.resource_array(
|
||||
event_actor.clone(),
|
||||
"network-event".to_string(),
|
||||
ResourceArrayType::Available,
|
||||
stream,
|
||||
);
|
||||
}
|
||||
|
@ -76,56 +55,16 @@ pub(crate) fn handle_network_event(
|
|||
let actor = actors.find_mut::<NetworkEventActor>(&netevent_actor_name);
|
||||
// Store the response information in the actor
|
||||
actor.add_response(httpresponse);
|
||||
ResourcesUpdatedArray {
|
||||
updates: vec![
|
||||
UpdateEntry {
|
||||
update_type: "requestHeaders".to_owned(),
|
||||
data: serde_json::to_value(actor.request_headers()).unwrap(),
|
||||
},
|
||||
UpdateEntry {
|
||||
update_type: "requestCookies".to_owned(),
|
||||
data: serde_json::to_value(actor.request_cookies()).unwrap(),
|
||||
},
|
||||
UpdateEntry {
|
||||
update_type: "responseStart".to_owned(),
|
||||
data: serde_json::to_value(actor.response_start()).unwrap(),
|
||||
},
|
||||
UpdateEntry {
|
||||
update_type: "eventTimings".to_owned(),
|
||||
data: serde_json::to_value(EventTimingsUpdateMsg {
|
||||
total_time: actor.total_time().as_millis() as u64,
|
||||
})
|
||||
.unwrap(),
|
||||
},
|
||||
UpdateEntry {
|
||||
update_type: "securityInfo".to_owned(),
|
||||
data: serde_json::to_value(SecurityInfoUpdateMsg {
|
||||
state: "insecure".to_owned(),
|
||||
})
|
||||
.unwrap(),
|
||||
},
|
||||
UpdateEntry {
|
||||
update_type: "responseContent".to_owned(),
|
||||
data: serde_json::to_value(actor.response_content()).unwrap(),
|
||||
},
|
||||
UpdateEntry {
|
||||
update_type: "responseCookies".to_owned(),
|
||||
data: serde_json::to_value(actor.response_cookies()).unwrap(),
|
||||
},
|
||||
UpdateEntry {
|
||||
update_type: "responseHeaders".to_owned(),
|
||||
data: serde_json::to_value(actor.response_headers()).unwrap(),
|
||||
},
|
||||
],
|
||||
}
|
||||
actor.resource_updates()
|
||||
};
|
||||
|
||||
let browsing_context_actor =
|
||||
actors.find::<BrowsingContextActor>(&browsing_context_actor_name);
|
||||
for stream in &mut connections {
|
||||
browsing_context_actor.resource_available(
|
||||
browsing_context_actor.resource_array(
|
||||
resource.clone(),
|
||||
"resources-updated".to_string(),
|
||||
"network-event".to_string(),
|
||||
ResourceArrayType::Updated,
|
||||
stream,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,11 @@ use serde::Serialize;
|
|||
|
||||
use crate::protocol::JsonPacketStream;
|
||||
|
||||
pub enum ResourceArrayType {
|
||||
Available,
|
||||
Updated,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub(crate) struct ResourceAvailableReply<T: Serialize> {
|
||||
pub from: String,
|
||||
|
@ -19,24 +24,29 @@ pub(crate) struct ResourceAvailableReply<T: Serialize> {
|
|||
pub(crate) trait ResourceAvailable {
|
||||
fn actor_name(&self) -> String;
|
||||
|
||||
fn resource_available<T: Serialize>(
|
||||
fn resource_array<T: Serialize>(
|
||||
&self,
|
||||
resource: T,
|
||||
resource_type: String,
|
||||
array_type: ResourceArrayType,
|
||||
stream: &mut TcpStream,
|
||||
) {
|
||||
self.resources_available(vec![resource], resource_type, stream);
|
||||
self.resources_array(vec![resource], resource_type, array_type, stream);
|
||||
}
|
||||
|
||||
fn resources_available<T: Serialize>(
|
||||
fn resources_array<T: Serialize>(
|
||||
&self,
|
||||
resources: Vec<T>,
|
||||
resource_type: String,
|
||||
array_type: ResourceArrayType,
|
||||
stream: &mut TcpStream,
|
||||
) {
|
||||
let msg = ResourceAvailableReply::<T> {
|
||||
from: self.actor_name(),
|
||||
type_: "resources-available-array".into(),
|
||||
type_: match array_type {
|
||||
ResourceArrayType::Available => "resources-available-array".to_string(),
|
||||
ResourceArrayType::Updated => "resources-updated-array".to_string(),
|
||||
},
|
||||
array: vec![(resource_type, resources)],
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue