Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F8613779
fetcher.ex
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
16 KB
Referenced Files
None
Subscribers
None
fetcher.ex
View Options
defmodule
Pleroma.LoadTesting.Fetcher
do
alias
Pleroma.Activity
alias
Pleroma.Pagination
alias
Pleroma.Repo
alias
Pleroma.User
alias
Pleroma.Web.ActivityPub.ActivityPub
alias
Pleroma.Web.MastodonAPI.MastodonAPI
alias
Pleroma.Web.MastodonAPI.StatusView
@spec
run_benchmarks
(
User
.
t
())
::
any
()
def
run_benchmarks
(
user
)
do
fetch_user
(
user
)
fetch_timelines
(
user
)
render_views
(
user
)
end
defp
formatters
do
[
Benchee.Formatters.Console
]
end
defp
fetch_user
(
user
)
do
Benchee
.
run
(
%{
"By id"
=>
fn
->
Repo
.
get_by
(
User
,
id
:
user
.
id
)
end
,
"By ap_id"
=>
fn
->
Repo
.
get_by
(
User
,
ap_id
:
user
.
ap_id
)
end
,
"By email"
=>
fn
->
Repo
.
get_by
(
User
,
email
:
user
.
email
)
end
,
"By nickname"
=>
fn
->
Repo
.
get_by
(
User
,
nickname
:
user
.
nickname
)
end
},
formatters
:
formatters
()
)
end
defp
create_filter
(
user
)
do
Pleroma.Filter
.
create
(%
Pleroma.Filter
{
user_id
:
user
.
id
,
phrase
:
"must be filtered"
,
hide
:
true
})
end
defp
delete_filter
(
filter
),
do
:
Repo
.
delete
(
filter
)
defp
fetch_timelines
(
user
)
do
fetch_home_timeline
(
user
)
fetch_home_timeline_with_filter
(
user
)
fetch_direct_timeline
(
user
)
fetch_public_timeline
(
user
)
fetch_public_timeline_with_filter
(
user
)
fetch_public_timeline
(
user
,
:with_blocks
)
fetch_public_timeline
(
user
,
:local
)
fetch_public_timeline
(
user
,
:tag
)
fetch_notifications
(
user
)
fetch_favourites
(
user
)
fetch_long_thread
(
user
)
fetch_timelines_with_reply_filtering
(
user
)
end
defp
render_views
(
user
)
do
render_timelines
(
user
)
render_long_thread
(
user
)
end
defp
opts_for_home_timeline
(
user
)
do
%{
blocking_user
:
user
,
count
:
"20"
,
muting_user
:
user
,
type
:
[
"Create"
,
"Announce"
],
user
:
user
,
with_muted
:
true
}
end
defp
fetch_home_timeline
(
user
,
title_end
\\
""
)
do
opts
=
opts_for_home_timeline
(
user
)
recipients
=
[
user
.
ap_id
|
User
.
following
(
user
)]
first_page_last
=
ActivityPub
.
fetch_activities
(
recipients
,
opts
)
|>
Enum
.
reverse
()
|>
List
.
last
()
second_page_last
=
ActivityPub
.
fetch_activities
(
recipients
,
Map
.
put
(
opts
,
:max_id
,
first_page_last
.
id
))
|>
Enum
.
reverse
()
|>
List
.
last
()
third_page_last
=
ActivityPub
.
fetch_activities
(
recipients
,
Map
.
put
(
opts
,
:max_id
,
second_page_last
.
id
))
|>
Enum
.
reverse
()
|>
List
.
last
()
forth_page_last
=
ActivityPub
.
fetch_activities
(
recipients
,
Map
.
put
(
opts
,
:max_id
,
third_page_last
.
id
))
|>
Enum
.
reverse
()
|>
List
.
last
()
title
=
"home timeline "
<>
title_end
Benchee
.
run
(
%{
title
=>
fn
opts
->
ActivityPub
.
fetch_activities
(
recipients
,
opts
)
end
},
inputs
:
%{
"1 page"
=>
opts
,
"2 page"
=>
Map
.
put
(
opts
,
:max_id
,
first_page_last
.
id
),
"3 page"
=>
Map
.
put
(
opts
,
:max_id
,
second_page_last
.
id
),
"4 page"
=>
Map
.
put
(
opts
,
:max_id
,
third_page_last
.
id
),
"5 page"
=>
Map
.
put
(
opts
,
:max_id
,
forth_page_last
.
id
),
"1 page only media"
=>
Map
.
put
(
opts
,
:only_media
,
true
),
"2 page only media"
=>
Map
.
put
(
opts
,
:max_id
,
first_page_last
.
id
)
|>
Map
.
put
(
:only_media
,
true
),
"3 page only media"
=>
Map
.
put
(
opts
,
:max_id
,
second_page_last
.
id
)
|>
Map
.
put
(
:only_media
,
true
),
"4 page only media"
=>
Map
.
put
(
opts
,
:max_id
,
third_page_last
.
id
)
|>
Map
.
put
(
:only_media
,
true
),
"5 page only media"
=>
Map
.
put
(
opts
,
:max_id
,
forth_page_last
.
id
)
|>
Map
.
put
(
:only_media
,
true
)
},
formatters
:
formatters
()
)
end
defp
fetch_home_timeline_with_filter
(
user
)
do
{
:ok
,
filter
}
=
create_filter
(
user
)
fetch_home_timeline
(
user
,
"with filters"
)
delete_filter
(
filter
)
end
defp
opts_for_direct_timeline
(
user
)
do
%{
visibility
:
"direct"
,
blocking_user
:
user
,
count
:
"20"
,
type
:
"Create"
,
user
:
user
,
with_muted
:
true
}
end
defp
fetch_direct_timeline
(
user
)
do
recipients
=
[
user
.
ap_id
]
opts
=
opts_for_direct_timeline
(
user
)
first_page_last
=
recipients
|>
ActivityPub
.
fetch_activities_query
(
opts
)
|>
Pagination
.
fetch_paginated
(
opts
)
|>
List
.
last
()
opts2
=
Map
.
put
(
opts
,
:max_id
,
first_page_last
.
id
)
second_page_last
=
recipients
|>
ActivityPub
.
fetch_activities_query
(
opts2
)
|>
Pagination
.
fetch_paginated
(
opts2
)
|>
List
.
last
()
opts3
=
Map
.
put
(
opts
,
:max_id
,
second_page_last
.
id
)
third_page_last
=
recipients
|>
ActivityPub
.
fetch_activities_query
(
opts3
)
|>
Pagination
.
fetch_paginated
(
opts3
)
|>
List
.
last
()
opts4
=
Map
.
put
(
opts
,
:max_id
,
third_page_last
.
id
)
forth_page_last
=
recipients
|>
ActivityPub
.
fetch_activities_query
(
opts4
)
|>
Pagination
.
fetch_paginated
(
opts4
)
|>
List
.
last
()
Benchee
.
run
(
%{
"direct timeline"
=>
fn
opts
->
ActivityPub
.
fetch_activities_query
(
recipients
,
opts
)
|>
Pagination
.
fetch_paginated
(
opts
)
end
},
inputs
:
%{
"1 page"
=>
opts
,
"2 page"
=>
opts2
,
"3 page"
=>
opts3
,
"4 page"
=>
opts4
,
"5 page"
=>
Map
.
put
(
opts4
,
:max_id
,
forth_page_last
.
id
)
},
formatters
:
formatters
()
)
end
defp
opts_for_public_timeline
(
user
)
do
%{
type
:
[
"Create"
,
"Announce"
],
local_only
:
false
,
blocking_user
:
user
,
muting_user
:
user
}
end
defp
opts_for_public_timeline
(
user
,
:local
)
do
%{
type
:
[
"Create"
,
"Announce"
],
local_only
:
true
,
blocking_user
:
user
,
muting_user
:
user
}
end
defp
opts_for_public_timeline
(
user
,
:tag
)
do
%{
blocking_user
:
user
,
count
:
"20"
,
local_only
:
nil
,
muting_user
:
user
,
tag
:
[
"tag"
],
tag_all
:
[],
tag_reject
:
[],
type
:
"Create"
,
user
:
user
,
with_muted
:
true
}
end
defp
fetch_public_timeline
(
user
)
do
opts
=
opts_for_public_timeline
(
user
)
fetch_public_timeline
(
opts
,
"public timeline"
)
end
defp
fetch_public_timeline_with_filter
(
user
)
do
{
:ok
,
filter
}
=
create_filter
(
user
)
opts
=
opts_for_public_timeline
(
user
)
fetch_public_timeline
(
opts
,
"public timeline with filters"
)
delete_filter
(
filter
)
end
defp
fetch_public_timeline
(
user
,
:local
)
do
opts
=
opts_for_public_timeline
(
user
,
:local
)
fetch_public_timeline
(
opts
,
"public timeline only local"
)
end
defp
fetch_public_timeline
(
user
,
:tag
)
do
opts
=
opts_for_public_timeline
(
user
,
:tag
)
fetch_public_timeline
(
opts
,
"hashtag timeline"
)
end
defp
fetch_public_timeline
(
user
,
:only_media
)
do
opts
=
opts_for_public_timeline
(
user
)
|>
Map
.
put
(
:only_media
,
true
)
fetch_public_timeline
(
opts
,
"public timeline only media"
)
end
defp
fetch_public_timeline
(
user
,
:with_blocks
)
do
opts
=
opts_for_public_timeline
(
user
)
remote_non_friends
=
Agent
.
get
(
:non_friends_remote
,
&
&1
)
Benchee
.
run
(%{
"public timeline without blocks"
=>
fn
->
ActivityPub
.
fetch_public_activities
(
opts
)
end
})
Enum
.
each
(
remote_non_friends
,
fn
non_friend
->
{
:ok
,
_
}
=
User
.
block
(
user
,
non_friend
)
end
)
user
=
User
.
get_by_id
(
user
.
id
)
opts
=
Map
.
put
(
opts
,
:blocking_user
,
user
)
Benchee
.
run
(%{
"public timeline with user block"
=>
fn
->
ActivityPub
.
fetch_public_activities
(
opts
)
end
})
domains
=
Enum
.
reduce
(
remote_non_friends
,
[],
fn
non_friend
,
domains
->
{
:ok
,
_user
}
=
User
.
unblock
(
user
,
non_friend
)
%{
host
:
host
}
=
URI
.
parse
(
non_friend
.
ap_id
)
[
host
|
domains
]
end
)
domains
=
Enum
.
uniq
(
domains
)
Enum
.
each
(
domains
,
fn
domain
->
{
:ok
,
_
}
=
User
.
block_domain
(
user
,
domain
)
end
)
user
=
User
.
get_by_id
(
user
.
id
)
opts
=
Map
.
put
(
opts
,
:blocking_user
,
user
)
Benchee
.
run
(%{
"public timeline with domain block"
=>
fn
->
ActivityPub
.
fetch_public_activities
(
opts
)
end
})
end
defp
fetch_public_timeline
(
opts
,
title
)
when
is_binary
(
title
)
do
first_page_last
=
ActivityPub
.
fetch_public_activities
(
opts
)
|>
List
.
last
()
second_page_last
=
ActivityPub
.
fetch_public_activities
(
Map
.
put
(
opts
,
:max_id
,
first_page_last
.
id
))
|>
List
.
last
()
third_page_last
=
ActivityPub
.
fetch_public_activities
(
Map
.
put
(
opts
,
:max_id
,
second_page_last
.
id
))
|>
List
.
last
()
forth_page_last
=
ActivityPub
.
fetch_public_activities
(
Map
.
put
(
opts
,
:max_id
,
third_page_last
.
id
))
|>
List
.
last
()
Benchee
.
run
(
%{
title
=>
fn
opts
->
ActivityPub
.
fetch_public_activities
(
opts
)
end
},
inputs
:
%{
"1 page"
=>
opts
,
"2 page"
=>
Map
.
put
(
opts
,
:max_id
,
first_page_last
.
id
),
"3 page"
=>
Map
.
put
(
opts
,
:max_id
,
second_page_last
.
id
),
"4 page"
=>
Map
.
put
(
opts
,
:max_id
,
third_page_last
.
id
),
"5 page"
=>
Map
.
put
(
opts
,
:max_id
,
forth_page_last
.
id
)
},
formatters
:
formatters
()
)
end
defp
opts_for_notifications
do
%{
count
:
"20"
,
with_muted
:
true
}
end
defp
fetch_notifications
(
user
)
do
opts
=
opts_for_notifications
()
first_page_last
=
MastodonAPI
.
get_notifications
(
user
,
opts
)
|>
List
.
last
()
second_page_last
=
MastodonAPI
.
get_notifications
(
user
,
Map
.
put
(
opts
,
:max_id
,
first_page_last
.
id
))
|>
List
.
last
()
third_page_last
=
MastodonAPI
.
get_notifications
(
user
,
Map
.
put
(
opts
,
:max_id
,
second_page_last
.
id
))
|>
List
.
last
()
forth_page_last
=
MastodonAPI
.
get_notifications
(
user
,
Map
.
put
(
opts
,
:max_id
,
third_page_last
.
id
))
|>
List
.
last
()
Benchee
.
run
(
%{
"Notifications"
=>
fn
opts
->
MastodonAPI
.
get_notifications
(
user
,
opts
)
end
},
inputs
:
%{
"1 page"
=>
opts
,
"2 page"
=>
Map
.
put
(
opts
,
:max_id
,
first_page_last
.
id
),
"3 page"
=>
Map
.
put
(
opts
,
:max_id
,
second_page_last
.
id
),
"4 page"
=>
Map
.
put
(
opts
,
:max_id
,
third_page_last
.
id
),
"5 page"
=>
Map
.
put
(
opts
,
:max_id
,
forth_page_last
.
id
)
},
formatters
:
formatters
()
)
end
defp
fetch_favourites
(
user
)
do
first_page_last
=
ActivityPub
.
fetch_favourites
(
user
)
|>
List
.
last
()
second_page_last
=
ActivityPub
.
fetch_favourites
(
user
,
%{
:max_id
=>
first_page_last
.
id
})
|>
List
.
last
()
third_page_last
=
ActivityPub
.
fetch_favourites
(
user
,
%{
:max_id
=>
second_page_last
.
id
})
|>
List
.
last
()
forth_page_last
=
ActivityPub
.
fetch_favourites
(
user
,
%{
:max_id
=>
third_page_last
.
id
})
|>
List
.
last
()
Benchee
.
run
(
%{
"Favourites"
=>
fn
opts
->
ActivityPub
.
fetch_favourites
(
user
,
opts
)
end
},
inputs
:
%{
"1 page"
=>
%{},
"2 page"
=>
%{
:max_id
=>
first_page_last
.
id
},
"3 page"
=>
%{
:max_id
=>
second_page_last
.
id
},
"4 page"
=>
%{
:max_id
=>
third_page_last
.
id
},
"5 page"
=>
%{
:max_id
=>
forth_page_last
.
id
}
},
formatters
:
formatters
()
)
end
defp
opts_for_long_thread
(
user
)
do
%{
blocking_user
:
user
,
user
:
user
}
end
defp
fetch_long_thread
(
user
)
do
%{
public_thread
:
public
,
private_thread
:
private
}
=
Agent
.
get
(
:benchmark_state
,
fn
state
->
state
end
)
opts
=
opts_for_long_thread
(
user
)
private_input
=
{
private
.
data
[
"context"
],
Map
.
put
(
opts
,
:exclude_id
,
private
.
id
)}
public_input
=
{
public
.
data
[
"context"
],
Map
.
put
(
opts
,
:exclude_id
,
public
.
id
)}
Benchee
.
run
(
%{
"fetch context"
=>
fn
{
context
,
opts
}
->
ActivityPub
.
fetch_activities_for_context
(
context
,
opts
)
end
},
inputs
:
%{
"Private long thread"
=>
private_input
,
"Public long thread"
=>
public_input
},
formatters
:
formatters
()
)
end
defp
render_timelines
(
user
)
do
opts
=
opts_for_home_timeline
(
user
)
recipients
=
[
user
.
ap_id
|
User
.
following
(
user
)]
home_activities
=
ActivityPub
.
fetch_activities
(
recipients
,
opts
)
|>
Enum
.
reverse
()
recipients
=
[
user
.
ap_id
]
opts
=
opts_for_direct_timeline
(
user
)
direct_activities
=
recipients
|>
ActivityPub
.
fetch_activities_query
(
opts
)
|>
Pagination
.
fetch_paginated
(
opts
)
opts
=
opts_for_public_timeline
(
user
)
public_activities
=
ActivityPub
.
fetch_public_activities
(
opts
)
opts
=
opts_for_public_timeline
(
user
,
:tag
)
tag_activities
=
ActivityPub
.
fetch_public_activities
(
opts
)
opts
=
opts_for_notifications
()
notifications
=
MastodonAPI
.
get_notifications
(
user
,
opts
)
favourites
=
ActivityPub
.
fetch_favourites
(
user
)
Benchee
.
run
(
%{
"Rendering home timeline"
=>
fn
->
StatusView
.
render
(
"index.json"
,
%{
activities
:
home_activities
,
for
:
user
,
as
:
:activity
})
end
,
"Rendering direct timeline"
=>
fn
->
StatusView
.
render
(
"index.json"
,
%{
activities
:
direct_activities
,
for
:
user
,
as
:
:activity
})
end
,
"Rendering public timeline"
=>
fn
->
StatusView
.
render
(
"index.json"
,
%{
activities
:
public_activities
,
for
:
user
,
as
:
:activity
})
end
,
"Rendering tag timeline"
=>
fn
->
StatusView
.
render
(
"index.json"
,
%{
activities
:
tag_activities
,
for
:
user
,
as
:
:activity
})
end
,
"Rendering notifications"
=>
fn
->
Pleroma.Web.MastodonAPI.NotificationView
.
render
(
"index.json"
,
%{
notifications
:
notifications
,
for
:
user
})
end
,
"Rendering favourites timeline"
=>
fn
->
StatusView
.
render
(
"index.json"
,
%{
activities
:
favourites
,
for
:
user
,
as
:
:activity
})
end
},
formatters
:
formatters
()
)
end
defp
render_long_thread
(
user
)
do
%{
public_thread
:
public
,
private_thread
:
private
}
=
Agent
.
get
(
:benchmark_state
,
fn
state
->
state
end
)
opts
=
%{
for
:
user
}
public_activity
=
Activity
.
get_by_id_with_object
(
public
.
id
)
private_activity
=
Activity
.
get_by_id_with_object
(
private
.
id
)
Benchee
.
run
(
%{
"render"
=>
fn
opts
->
StatusView
.
render
(
"show.json"
,
opts
)
end
},
inputs
:
%{
"Public root"
=>
Map
.
put
(
opts
,
:activity
,
public_activity
),
"Private root"
=>
Map
.
put
(
opts
,
:activity
,
private_activity
)
},
formatters
:
formatters
()
)
fetch_opts
=
opts_for_long_thread
(
user
)
public_context
=
ActivityPub
.
fetch_activities_for_context
(
public
.
data
[
"context"
],
Map
.
put
(
fetch_opts
,
:exclude_id
,
public
.
id
)
)
private_context
=
ActivityPub
.
fetch_activities_for_context
(
private
.
data
[
"context"
],
Map
.
put
(
fetch_opts
,
:exclude_id
,
private
.
id
)
)
Benchee
.
run
(
%{
"render"
=>
fn
opts
->
StatusView
.
render
(
"context.json"
,
opts
)
end
},
inputs
:
%{
"Public context"
=>
%{
user
:
user
,
activity
:
public_activity
,
activities
:
public_context
},
"Private context"
=>
%{
user
:
user
,
activity
:
private_activity
,
activities
:
private_context
}
},
formatters
:
formatters
()
)
end
defp
fetch_timelines_with_reply_filtering
(
user
)
do
public_params
=
opts_for_public_timeline
(
user
)
Benchee
.
run
(
%{
"Public timeline without reply filtering"
=>
fn
->
ActivityPub
.
fetch_public_activities
(
public_params
)
end
,
"Public timeline with reply filtering - following"
=>
fn
->
public_params
|>
Map
.
put
(
:reply_visibility
,
"following"
)
|>
Map
.
put
(
:reply_filtering_user
,
user
)
|>
ActivityPub
.
fetch_public_activities
()
end
,
"Public timeline with reply filtering - self"
=>
fn
->
public_params
|>
Map
.
put
(
:reply_visibility
,
"self"
)
|>
Map
.
put
(
:reply_filtering_user
,
user
)
|>
ActivityPub
.
fetch_public_activities
()
end
},
formatters
:
formatters
()
)
private_params
=
opts_for_home_timeline
(
user
)
recipients
=
[
user
.
ap_id
|
User
.
following
(
user
)]
Benchee
.
run
(
%{
"Home timeline without reply filtering"
=>
fn
->
ActivityPub
.
fetch_activities
(
recipients
,
private_params
)
end
,
"Home timeline with reply filtering - following"
=>
fn
->
private_params
=
private_params
|>
Map
.
put
(
:reply_filtering_user
,
user
)
|>
Map
.
put
(
:reply_visibility
,
"following"
)
ActivityPub
.
fetch_activities
(
recipients
,
private_params
)
end
,
"Home timeline with reply filtering - self"
=>
fn
->
private_params
=
private_params
|>
Map
.
put
(
:reply_filtering_user
,
user
)
|>
Map
.
put
(
:reply_visibility
,
"self"
)
ActivityPub
.
fetch_activities
(
recipients
,
private_params
)
end
},
formatters
:
formatters
()
)
end
end
File Metadata
Details
Attached
Mime Type
text/x-ruby
Expires
Sat, Oct 25, 7:26 PM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
549640
Default Alt Text
fetcher.ex (16 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment