Index: wp-includes/option.php
===================================================================
--- wp-includes/option.php	(revision 29359)
+++ wp-includes/option.php	(working copy)
@@ -703,6 +703,60 @@
 }
 
 /**
+* Get the value of a transient if it exists, if it has expired then refresh the
+* value via the callback passed in and continue returning the stale value for
+* subsquent calls for 1 minute.
+*
+* If no stale values exist in cache use the default value passed in as the
+* initial stale value.
+*
+* @since 4.x
+*
+* @param string   $transient  Transient name. Expected to not be SQL-escaped.
+*                             Must be 45 characters or fewer in length.
+* @param callable $callback   PHP callback used to generate transient value.
+*                             Must be serializable if non-scalar. Expected to
+*                             not be SQL-escaped.
+* @param int      $expiration Optional. Time until expiration in seconds.
+*                             Default 0.
+* @param mixed    $default    Optional. The initial stale cache value. Default
+*                             false.
+* @return mixed Value of transient.
+*/
+function get_set_soft_transient( $transient, $callback, $expiration = 0, $default = false ) {
+	$soft_timeout = 60;
+	$value = get_transient( $transient );
+
+	// Nothing in cache so construct default stale value
+	if ( !isset( $value['_meta'] ) ) {
+		$value = array(
+			'_meta' => array(
+				'refreshing' => false,
+				'expires' => 0,
+			),
+			'payload' => $default,
+		);
+	}
+
+	// Cache refresh needed and no one else is currently refreshing it
+	if ( !$value['_meta']['refreshing'] && -1 != $value['_meta']['expires'] && time() > $value['_meta']['expires'] ) {
+		// Cache refreshing status so we can return stale values for 1 min
+		$value['_meta']['refreshing'] = true;
+		set_transient( $transient, $value, $soft_timeout );
+
+		// Run slow action and cache results
+		$value['payload'] = call_user_func( $callback );
+		$value['_meta'] = array(
+			'refreshing' => false,
+			'expires' => ( 0 === $expiration ? -1 : time() + $expiration ),
+		);
+		set_transient( $transient, $value, ( 0 === $expiration ? 0 : $soft_timeout + $expiration ) );
+	}
+
+	return $value['payload'];
+}
+
+/**
  * Saves and restores user interface settings stored in a cookie.
  *
  * Checks if the current user-settings cookie is updated and stores it. When no
