Category Archives: thirdspace

Weekly Web Harvest for 2018-08-05

  • When You Hear _______, Pay Attention – Hacker Noon
    … you’re about to fall into a trap and need to pay attention):

    Might as well do [some extra thing] while we [do the original thing]

  • Fallout 76’s Downright Exciting Plan to Deal With Griefing and Trolls :: Games :: Features :: Fallout 76 :: Paste
    Howard says they wanted the game to have an element of danger without griefing, which is a tall order in an open world online game. To achieve this, they implemented features that will greatly reduce any incentive to grief other players, and turn those that do into the villains. For example, when you shoot another player, your character only does a small amount of damage, with more damage awarded if you continue and engage and enter into PvP. Players who die may seek revenge for their deaths, gaining double reward of caps and XP. Players that kill those who didn’t want to be engaged are labeled a “wanted murderer” and have a bounty placed on their head. If you are labeled a wanted murderer, you will receive no reward for those kills. Wanted murderers will also appear on your map as a red star denoting the bounty on their head, and the bounty comes out of their personal stash of caps. They also cannot see the other characters on the map.
  • Data to Viz | A collection of graphic pitfalls
    Nice tips.
  • Welcome to Coyote | Coyote
    –would also make for an interesting project for English and art classes

    The open-source Coyote software was developed by the Museum of Contemporary Art Chicago to support a distributed workflow for describing images in our web CMS and publishing those descriptions to our public website. The MCA team is creating both alt-text descriptions of 20–30 words, as well as much longer descriptions, particularly of collection works.

Update Group Fields ACF

In this case, I was trying to create a post and update the fields in an ACF group via WordPress’s wp_insert_post and the documentation on the ACF site ended up being incomplete on this.

function make_member_post(){
//THE WordPress PART
	$user = get_user_by( 'email', 'some_email@email.com' );
	$user_id = $user->ID;
	$args = array(
	    'author'        =>  $user_id,
		'post_type' => 'member', 
		'post_status' => 'publish',
		'post_title' => 'does not matter',  
    );
    $new_memmber = wp_insert_post($args);   

//THE ACF PART
	$field_key = 'THIS_WILL_BE_FROM_ACF_FOR_YOUR_GROUP';
	$values = array(
		'first_name'	=>	'joe',//THE 1st PART MATCHES YOUR FIELD NAMES, THE 2nd IS THE VALUE YOU WANT
		'last_name'	=>	'smith',
	);
	update_field( $field_key, $values, $new_memmber );
}

Update Group Fields ACF

In this case, I was trying to create a post and update the fields in an ACF group via WordPress’s wp_insert_post and the documentation on the ACF site ended up being incomplete on this.

function make_member_post(){
//THE WordPress PART
	$user = get_user_by( 'email', 'some_email@email.com' );
	$user_id = $user->ID;
	$args = array(
	    'author'        =>  $user_id,
		'post_type' => 'member', 
		'post_status' => 'publish',
		'post_title' => 'does not matter',  
    );
    $new_memmber = wp_insert_post($args);   

//THE ACF PART
	$field_key = 'THIS_WILL_BE_FROM_ACF_FOR_YOUR_GROUP';
	$values = array(
		'first_name'	=>	'joe',//THE 1st PART MATCHES YOUR FIELD NAMES, THE 2nd IS THE VALUE YOU WANT
		'last_name'	=>	'smith',
	);
	update_field( $field_key, $values, $new_memmber );
}

Load Testing WordPress Multisite

Load Testing WordPress Multisite

Over the last few weeks, we’ve been dealing with some heavy fallout from a recent server migration on our large WordPress MU installation. While moving everything from Linode to Digital Ocean should give us a more powerful toolset, save on costs, and give us more infrastructure flexibility, I wish the cut over was uneventful.

On Friday we spent the better part of our day working with the team at Reclaim Hosting to troubleshoot some issues we were having, and one day I or one of my other compatriots might feel brave enough to document that crusade in a post to enshrine the great display of teamwork that pulled off a clutch save. Or write the other post shaming us for our poor testing patterns : )

However, after the switch sat for a few days, we ran into a scenario where MySQL started to eat through the available memory on the server, all the way up to 96 GB of RAM. Obviously this was unsustainable, so Tim at Reclaim suggested swapping out MySQL for MariaDB, which is a drop-in enhancement for MySQL.

Tim wired this up on our staging server, and it seemed to pretty immediately level out our database performance. However, we wanted to do some basic load testing of this new setup to make sure that performance would stay the same as our usage increased.

You can see some of these represented in the dramatic drop in the green part of this area chart below:

 

After that new usage level stayed stable for a day or so, we decided to do some load testing on both servers to test some of these assumptions. Once we got down to it, we felt like existing load testing tools didn’t give us a great picture of how our setup might get hit under live load.

For example, we use NGINX as a proxy to Apache, and NGINX does a great job of caching frequently used resources. However, since we have 30K sites on this multisite, we’re not talking about tons of traffic to a few popular pages; instead, we are looking at fresh loads on lots of different sites, which might actually impact SQL performance.

When NGINX responds with a cached page or asset, nothing actually gets through to MySQL at all.

Since most existing load testing tools let you focus on throwing a lot of traffic at a few urls, we decided to write up a quick testing script that would loop through a larger CSV file of our 100 most popular sites as per our analytics data.

You can find a link to the GitHub repo here, but I posted the meat of the code below:

import csv
import requests
import chardet
import time

def check_traffic():
    while True:
        with open('./page_urls.csv', 'rb') as csv_file:
            result = chardet.detect(csv_file.read())
        with open('./page_urls.csv', 'r', encoding=result['encoding']) as encoded_file:
            rows = csv.reader(encoded_file)
            for row in rows:
                url = "http://staging.rampages.us/" + row[0]
                print("getting url: " + url)
                r = requests.get(url)
                res = {"url": url, "status_code": r.status_code, "test": r.text }
                print(res)
                time.sleep(.2)

check_traffic()

This quick script did a great job of getting a ton of requests past the NGINX caching on an initial pass, which let us evaluate the performance metrics we were interested in on the backend. However, this was a pretty manual process of logging into the server via SSH, running the top or htop command, kicking of the load test via local command line, then monitoring the top output in a separate terminal window.

While this was helpful for our particular purposes, it really highlighted to us how far some of the load testing tools need to grow in terms of their usefulness, especially for the non-standard WP set-up, once you get outside of caring about latency at a single url.

In our wrap-up discussion, we talked about where we think load testing for WordPress should head in the future:

  • Easy plugin installation to allow load test to perform post creation, post update, comment creation, and media uploads as a part of the load test. For anyone using WP MU as an authoring platform, once you hit a certain scale, reads on your database aren’t the biggest deal, it’s when you have 1000 authors working at the same time that things start to move sideways.
  • Anyone running a large WP installation knows that plugins and even perhaps themes are not made and distributed equally. Thus, focusing on one or two main URLs can lull us into a false level of confidence regarding how other sites, maybe less under our direct control, are performing.
  • Actually simulate browser traffic instead of examining latency with just the initial HTML response. For example, the tool loader.io makes 10,000 or more requests to the same URL and tracks the response time for each request. However, this isn’t really helpful in getting the full picture of how your site would respond under actual load. When the browser parses your HTML, it fires off additional script/style/asset requests that will all place additional load on your server. It is easy to see from a data transfer perspective why the load testing companies don’t simulate a browser. In our test with 500 clients, our total bandwidth consumption for all of the tests was somewhere around 5 MB, but when I calculated the cost to have 500 clients download the entire page weight, it was somewhere around 2.5 GB.
  • Right now, it seems like most performance testing tools involve chucking way more clients than realistic at a site so that we get a feel good sense that things are working well. But for most of us, 10,000 clients in 5 minutes downloading a single cached HTML page is far from realistic. We think it would be cool if a load testing tool could integrate with your Google Analytics data to simulate a load that would be realistically stressful for your application using historical data.

Overall, this has been an exciting foray into a part of development I’ve never really touched, but at the end of the day I’m left feeling disappointed by the existing options out there for load/performance/stress testing, especially when related to WordPress. I’m interested in how other people in the community handle this. I’m sure I’ve overlooked more capable tools, or sussed out problems that don’t exist for the community at-large.

 

The post Load Testing WordPress Multisite appeared first on Jeff Everhart.

Super Cleansing Cut/Paste into Tiny MCE in WordPress

Had someone cut/pasting from Google Docs into WordPress and it was ending up littered with internal style elements and super irritating span classes. I found this post which got me 95% of the way there and just added .removeAttr(‘style’) to get rid of the inline styles.

Now I can just re-cut/paste and get a clean chunk of text.


//fix cut paste drama from https://jonathannicol.com/blog/2015/02/19/clean-pasted-text-in-wordpress/
add_filter('tiny_mce_before_init','configure_tinymce');

/**
* Customize TinyMCE's configuration
*
* @param array
* @return array
*/
function configure_tinymce($in) {
$in['paste_preprocess'] = "function(plugin, args){
// Strip all HTML tags except those we have whitelisted
var whitelist = 'p,b,strong,i,em,h3,h4,h5,h6,ul,li,ol';
var stripped = jQuery('<div>' + args.content + '</div>');
var els = stripped.find('*').not(whitelist);
for (var i = els.length - 1; i >= 0; i--) {
var e = els[i];
jQuery(e).replaceWith(e.innerHTML);
}
// Strip all class and id attributes
stripped.find('*').removeAttr('id').removeAttr('class').removeAttr('style');
// Return the clean HTML
args.content = stripped.html();
}";
return $in;
}

Contact us

Academic Learning Transformation Lab - ALT Lab
1000 Floyd Ave, Suite 4102 | Richmond, Virginia 23284
altlab@vcu.edu | 804-828-6786

Last updated: July 31, 2018

Virginia Commonwealth University

Privacy | Accessibility | Webmaster