GettingStarted - taking care of connection_state when starting connections

This commit is contained in:
Pawel Kadluczka 2014-10-31 17:42:53 -07:00
Родитель 7d190aedf4
Коммит 41838a9d81
5 изменённых файлов: 66 добавлений и 7 удалений

Просмотреть файл

@ -12,7 +12,7 @@ namespace signalr
class web_exception : public std::runtime_error
{
public:
explicit web_exception(const utility::string_t &what)
explicit web_exception(const utility::string_t &what)
: runtime_error(utility::conversions::to_utf8string(what))
{}
};

Просмотреть файл

@ -2,7 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include <cpprest\asyncrt_utils.h>
#include "connection_impl.h"
#include "request_sender.h"
namespace signalr
{
@ -14,11 +16,31 @@ namespace signalr
pplx::task<void> connection_impl::start()
{
if (!change_state(connection_state::disconnected, connection_state::connecting))
{
throw std::runtime_error(utility::conversions::to_utf8string(
_XPLATSTR("cannot start a connection that is not in the disconnected state")));
}
return pplx::task_from_result();
}
connection_state connection_impl::get_connection_state() const
{
return m_connection_state;
return m_connection_state.load();
}
bool connection_impl::change_state(connection_state old_state, connection_state new_state)
{
connection_state expected_state{ old_state };
if (!m_connection_state.compare_exchange_strong(expected_state, new_state, std::memory_order_seq_cst))
{
// TODO: add logging
// TODO: invoke state_changed callback
return false;
}
return true;
}
}

Просмотреть файл

@ -3,6 +3,7 @@
#pragma once
#include <atomic>
#include <cpprest\http_client.h>
#include "signalrclient\web_request_factory.h"
#include "signalrclient\transport_factory.h"
@ -29,9 +30,11 @@ namespace signalr
private:
web::uri m_base_uri;
utility::string_t m_querystring;
connection_state m_connection_state;
std::atomic<connection_state> m_connection_state;
web_request_factory &m_web_request_factory;
transport_factory& m_transport_factory;
bool change_state(connection_state old_state, connection_state new_state);
};
}

Просмотреть файл

@ -13,7 +13,41 @@ TEST(connection_impl_connection_state, initial_connection_state_is_disconnected)
web_request_factory request_factory;
transport_factory transport_factory;
ASSERT_EQ(
connection_state::disconnected,
connection_impl(_XPLATSTR("url"), _XPLATSTR(""), request_factory, transport_factory).get_connection_state());
connection_impl connection{ _XPLATSTR("url"), _XPLATSTR(""), request_factory, transport_factory };
ASSERT_EQ(connection_state::disconnected, connection.get_connection_state());
}
TEST(connection_impl_start, cannot_start_non_disconnected_exception)
{
web_request_factory request_factory;
transport_factory transport_factory;
connection_impl connection{ _XPLATSTR("url"), _XPLATSTR(""), request_factory, transport_factory };
connection.start().wait();
try
{
connection.start().wait();
ASSERT_TRUE(false); // exception not thrown
}
catch (const std::runtime_error& e)
{
ASSERT_EQ(
_XPLATSTR("cannot start a connection that is not in the disconnected state"),
utility::conversions::print_string(e.what()));
}
}
TEST(connection_impl_start, connection_state_is_connecting_when_connection_is_being_started)
{
web_request_factory request_factory;
transport_factory transport_factory;
connection_impl connection{ _XPLATSTR("url"), _XPLATSTR(""), request_factory, transport_factory };
connection.start().wait();
ASSERT_EQ(connection.get_connection_state(), connection_state::connecting);
}

Просмотреть файл

@ -25,7 +25,7 @@ TEST(http_sender_get_response, exception_thrown_if_status_code_not_200)
try
{
http_sender::get(request).get();
ASSERT_TRUE(false); // exception not thrown
ASSERT_TRUE(false); // exception not thrown
}
catch (const web_exception &e)
{