diff --git a/applications/gui2/src/views/addsource.cpp b/applications/gui2/src/views/addsource.cpp
index 699e9aef1b475768aa376f1287a8c07478e7ff3a..1f962b4970b0cea566bc1d557188175fd7cd5ae1 100644
--- a/applications/gui2/src/views/addsource.cpp
+++ b/applications/gui2/src/views/addsource.cpp
@@ -29,11 +29,9 @@ AddSourceWindow::AddSourceWindow(nanogui::Widget* parent, AddCtrl *ctrl) :
 	rebuild();
 
 	new_source_handle_ = ctrl_->feed()->onNewSources([this](int a) {
+		LOG(INFO) << "NEW SOURCES";
 		UNIQUE_LOCK(mutex_, lk);
-		// Note the 1, first widget is the title bar buttons
-		while(childCount() > 1) { removeChild(childCount()-1); }
-		rebuild();
-		screen()->performLayout();
+		do_rebuild_ = true;
 		return true;
 	});
 }
@@ -140,6 +138,17 @@ void AddSourceWindow::close() {
 	dispose();
 }
 
-//void AddSourceWindow::draw(NVGcontext *ctx) {
+void AddSourceWindow::draw(NVGcontext *ctx) {
+	{
+		UNIQUE_LOCK(mutex_, lk);
+		if (do_rebuild_) {
+			do_rebuild_ = false;
+			// Note the 1, first widget is the title bar buttons
+			while(childCount() > 1) { removeChild(childCount()-1); }
+			rebuild();
+			screen()->performLayout();
+		}
+	}
 
-//}
+	nanogui::Window::draw(ctx);
+}
diff --git a/applications/gui2/src/views/addsource.hpp b/applications/gui2/src/views/addsource.hpp
index fcca02ecca0c260ddf1fd94f64551b30320ab481..4d340f856c832fd28450adf94c43907c423b1b87 100644
--- a/applications/gui2/src/views/addsource.hpp
+++ b/applications/gui2/src/views/addsource.hpp
@@ -18,7 +18,7 @@ class AddSourceWindow : public nanogui::Window {
 	AddSourceWindow(nanogui::Widget *parent, AddCtrl *ctrl);
 	virtual ~AddSourceWindow();
 
-	//virtual void draw(NVGcontext *ctx);
+	virtual void draw(NVGcontext *ctx);
 
 private:
 	AddCtrl *ctrl_;
@@ -27,6 +27,7 @@ private:
 
 	ftl::Handle new_source_handle_;
 	MUTEX mutex_;
+	std::atomic_bool do_rebuild_=false;
 
 public:
 	// EIGEN_MAKE_ALIGNED_OPERATOR_NEW
diff --git a/components/control/cpp/src/master.cpp b/components/control/cpp/src/master.cpp
index a2913024aedd24c37b905b3eaa8f41239cfd4616..c0677c03d5ab597464b5fb412944abb24183e379 100644
--- a/components/control/cpp/src/master.cpp
+++ b/components/control/cpp/src/master.cpp
@@ -158,9 +158,9 @@ vector<string> Master::getConfigurables() {
 
 vector<string> Master::getConfigurables(const ftl::UUID &peer) {
 	try {
-		LOG(INFO) << "LISTING CONFIGS";
 		return net_->call<vector<string>>(peer, "list_configurables");
-	} catch (...) {
+	} catch (const ftl::exception &e) {
+		e.ignore();
 		return {};
 	}
 }
diff --git a/components/net/cpp/include/ftl/net/universe.hpp b/components/net/cpp/include/ftl/net/universe.hpp
index 37bdd1362199cede98464535027b25e158134ef9..6cc631a06ac509b96f615aa046c51bf5b55ded81 100644
--- a/components/net/cpp/include/ftl/net/universe.hpp
+++ b/components/net/cpp/include/ftl/net/universe.hpp
@@ -384,7 +384,7 @@ std::vector<R> Universe::findAll(const std::string &name, ARGS... args) {
 	{  // Block thread until async callback notifies us
 		//UNIQUE_LOCK(m,llk);
 		std::unique_lock<std::mutex> llk(m);
-		cv.wait_for(llk, std::chrono::seconds(1), [&returncount,&sentcount]{return returncount == sentcount;});
+		cv.wait_for(llk, std::chrono::seconds(1), [&returncount,sentcount]{return returncount == sentcount;});
 
 		// Cancel any further results
 		lk.lock();
diff --git a/components/net/cpp/src/peer.cpp b/components/net/cpp/src/peer.cpp
index 339e2f6670b48c0b1823cb6c6ebf1de6fe280158..7263281e8203139fb23da7211ab7a554cae6d1d6 100644
--- a/components/net/cpp/src/peer.cpp
+++ b/components/net/cpp/src/peer.cpp
@@ -130,22 +130,30 @@ static SOCKET tcpConnect(URI &uri, size_t ssize, size_t rsize) {
 	if (rc < 0) {
 		if (errno == EINPROGRESS) {
 			// FIXME:(Nick) Move to main select thread to prevent blocking
-			fd_set myset; 
+			fd_set myset;
+			fd_set errset; 
 			struct timeval tv;
 			tv.tv_sec = 1; 
 			tv.tv_usec = 0; 
 			FD_ZERO(&myset); 
-			FD_SET(csocket, &myset); 
-			rc = select(csocket+1u, NULL, &myset, NULL, &tv); 
-			if (rc <= 0) { //} && errno != EINTR) { 
+			FD_SET(csocket, &myset);
+			FD_ZERO(&errset); 
+			FD_SET(csocket, &errset); 
+
+			rc = select(csocket+1u, NULL, &myset, &errset, &tv); 
+			if (rc <= 0 || FD_ISSET(csocket, &errset)) { //} && errno != EINTR) { 
+				if (rc <= 0) {
+					LOG(ERROR) << "Could not connect to " << uri.getBaseURI();
+				} else {
+					LOG(ERROR) << "Could not connect (" << errno << ") " << uri.getBaseURI(); 	
+				}
+
 				#ifndef WIN32
 				close(csocket);
 				#else
 				closesocket(csocket);
 				#endif
 
-				LOG(ERROR) << "Could not connect to " << uri.getBaseURI();
-
 				return INVALID_SOCKET;
 			}
 		} else {
@@ -252,7 +260,7 @@ Peer::Peer(const char *pUri, Universe *u, Dispatcher *d) : can_reconnect_(true),
 				_badClose(false);
 			} else {
 				status_ = kConnecting;
-				LOG(INFO) << "WEB SOCK CONNECTED";
+				LOG(INFO) << "Websocket connected: " << pUri;
 			}
 		} else {
 			LOG(ERROR) << "Connection refused to " << uri.getHost() << ":" << uri.getPort();
diff --git a/components/rgbd-sources/src/sources/realsense/realsense_source.cpp b/components/rgbd-sources/src/sources/realsense/realsense_source.cpp
index 0aa4a1776b22f7c927dd5bd218400bdeb8a9c8fe..5b3ee5b6d34e22b50108f45c2d722a34ee6f887d 100644
--- a/components/rgbd-sources/src/sources/realsense/realsense_source.cpp
+++ b/components/rgbd-sources/src/sources/realsense/realsense_source.cpp
@@ -69,10 +69,17 @@ RealsenseSource::~RealsenseSource() {
 	
 }
 
+static bool rs_supported = false;
+static bool rs_init = false;
+
 bool RealsenseSource::supported() {
+	if (rs_init) return rs_supported;
+	rs_init = true;
+
 	rs2::context ctx;
 	auto devs = ctx.query_devices();
-	return devs.size() > 0;
+	rs_supported = devs.size() > 0;
+	return rs_supported;
 }
 
 bool RealsenseSource::capture(int64_t ts) {
diff --git a/components/rgbd-sources/src/sources/stereovideo/opencv.cpp b/components/rgbd-sources/src/sources/stereovideo/opencv.cpp
index cd9502709f9da35f39eea07a6b5e4bb3470ccb84..df3a9999d8113bdd45dacd203b9ffa1d290290fa 100644
--- a/components/rgbd-sources/src/sources/stereovideo/opencv.cpp
+++ b/components/rgbd-sources/src/sources/stereovideo/opencv.cpp
@@ -151,9 +151,11 @@ OpenCVDevice::~OpenCVDevice() {
 }
 
 static std::vector<ftl::rgbd::detail::DeviceDetails> opencv_devices;
+static bool opencv_dev_init = false;
 
 std::vector<ftl::rgbd::detail::DeviceDetails> OpenCVDevice::getDevices() {
-	if (opencv_devices.size() > 0) return opencv_devices;
+	if (opencv_dev_init) return opencv_devices;
+	opencv_dev_init = true;
 
 	std::vector<ftl::rgbd::detail::DeviceDetails> devices;
 
diff --git a/components/rgbd-sources/src/sources/stereovideo/pylon.cpp b/components/rgbd-sources/src/sources/stereovideo/pylon.cpp
index d9d270cdeb718ba9a4ec5c698a5e1d9e26fcd79e..cc3ac34ed6143724af34d4c95050473d59da9d59 100644
--- a/components/rgbd-sources/src/sources/stereovideo/pylon.cpp
+++ b/components/rgbd-sources/src/sources/stereovideo/pylon.cpp
@@ -114,7 +114,13 @@ PylonDevice::~PylonDevice() {
 
 }
 
+static std::vector<ftl::rgbd::detail::DeviceDetails> pylon_devices;
+static bool pylon_dev_init = false;
+
 std::vector<ftl::rgbd::detail::DeviceDetails> PylonDevice::listDevices() {
+	if (pylon_dev_init) return pylon_devices;
+	pylon_dev_init = true;
+
 	auto &inst = CTlFactory::GetInstance();
 
 	Pylon::DeviceInfoList_t devices;
@@ -132,6 +138,7 @@ std::vector<ftl::rgbd::detail::DeviceDetails> PylonDevice::listDevices() {
 		r.maxwidth = 0;
 	}
 
+	pylon_devices = results;
 	return results;
 }
 
diff --git a/components/streams/src/feed.cpp b/components/streams/src/feed.cpp
index 7dad368a14ee4828fe96ebbaf03f5cb5c50c355c..69ac3c24a1687592eafb5331efa74dbbe8c08ccc 100644
--- a/components/streams/src/feed.cpp
+++ b/components/streams/src/feed.cpp
@@ -144,13 +144,13 @@ Feed::Feed(nlohmann::json &config, ftl::net::Universe*net) :
 			// FIXME: Find better option that waiting here.
 			// Wait to make sure streams have started properly.
 			std::this_thread::sleep_for(std::chrono::milliseconds(100));
-			UNIQUE_LOCK(mtx_, lk);
+			//UNIQUE_LOCK(mtx_, lk);
 			updateNetSources();
 		});
 	});
 
 	net_->bind("add_stream", [this](std::string uri){
-		UNIQUE_LOCK(mtx_, lk);
+		//UNIQUE_LOCK(mtx_, lk);
 		updateNetSources();
 	});
 
@@ -425,9 +425,12 @@ void Feed::removeFilter(Feed::Filter* filter) {
 }
 
 void Feed::updateNetSources() {
-	netcams_ =
+	auto netcams =
 		net_->findAll<std::string>("list_streams");
 
+	UNIQUE_LOCK(mtx_, lk);
+	netcams_ = std::move(netcams);
+
 	if (value("auto_host_sources", false)) {
 		for (auto s : netcams_) {
 			ftl::URI uri(s);
@@ -447,7 +450,7 @@ void Feed::updateNetSources() {
 							<< stream->value("uri", std::string("NONE"))
 							<< " (" << fsid << ")";
 
-				cv_net_connect_.notify_one();
+				//cv_net_connect_.notify_one();
 			}
 			else {
 				LOG(INFO) << "Stream exists: " << s;
@@ -674,7 +677,7 @@ uint32_t Feed::add(const std::string &path) {
 		auto &host_details = known_hosts[uri.getBaseURIWithUser()];
 		host_details["last_open"] = ftl::timer::get_time();
 
-		net_->connect(path)->waitConnection();
+		ftl::pool.push([this,path](int id) { net_->connect(path); });
 
 	}
 	else if (scheme == ftl::URI::SCHEME_FTL) {