Вопрос, который вы связали , касается данных , а не соединений. Многопользовательская работа с глобальными данными нецелесообразна, потому что вы не можете понять, где эти сотрудники находятся в веб-приложении, чтобы синхронизировать их.
Решение этого вопроса заключается в использовании внешнего источника данных, такого как база данных, к которой необходимо каким-либо образом подключиться. Однако ваша идея иметь одно глобальное соединение небезопасна, поскольку несколько рабочих потоков будут взаимодействовать с ним одновременно и либо связываться друг с другом, либо ждать по одному для получения ресурса. Самый простой способ справиться с этим - установить соединение в каждом представлении, когда вам это нужно.
В этом примере показано, как создать уникальное соединение для каждого запроса без глобальных значений, повторно использовать соединение после его установления для запроса. Объект g
, хотя и выглядит как глобальный, реализован как локальный поток за кулисами, поэтому каждый работник получает свой собственный экземпляр g
и соединение, сохраненное в нем только во время одного запроса.
from flask import g
def get_conn():
"""Use this function to establish or get the already established
connection during a request. The connection is closed at the end
of the request. This avoids having a global connection by storing
the connection on the g object per request.
"""
if "conn" not in g:
g.conn = make_connection(...)
return g.conn
@app.teardown_request
def close_conn(e):
"""Automatically close the connection after the request if
it was opened.
"""
conn = g.pop("conn", None)
if conn is not None:
conn.close()
@app.route("/get_data")
def get_data():
# If something else has already used get_conn during the
# request, this will return the same connection. Anything
# that uses it after this will also use the same connection.
conn = get_conn()
data = conn.query(...)
return jsonify(data)
Вы можете со временем обнаружить, что установление нового соединения для каждого запроса является слишком дорогим, если у вас есть много тысяч одновременных запросов. Одним из решений является создание пула соединений для глобального хранения списка соединений с поточно-ориентированным способом получения и замены соединения в списке по мере необходимости. SQLAlchemy (и Flask-SQLAlchemy) использует эту технику. Многие библиотеки уже предоставляют реализации пула соединений, поэтому либо используйте их, либо используйте их в качестве справочного для своего.
Вместо того, чтобы использовать константы для сеансовых ключей, я использую свой собственный безопасный с точки зрения типов объект сессии, который похож на это (извините, это находится в C#, посмотрите ниже для версии VB):
public class MySession
{
// Private constructor (use MySession.Current to access the current instance).
private MySession() {}
// Gets the current session.
public static MySession Current
{
get
{
MySession session = HttpContext.Current.Session["__MySession__"] as MySession;
if (session == null)
{
session = new MySession();
HttpContext.Current.Session["__MySession__"] = session;
}
return session;
}
}
// My session data goes here:
public string MyString { get; set; };
public bool MyFlag { get; set; };
public int MyNumber { get; set; };
}
Каждый раз, когда мне нужно к чтению-записи что-то к/от сессии, я могу использовать свой безопасный с точки зрения типов объект сессии как это:
string s = MySession.Current.MyString;
s = "new value";
MySession.Current.MyString = s;
Это решение приводит к нескольким преимуществам:
Обновление: вот версия VB (автоматически преобразована из версии C#). Извините, но я не знаю VB и таким образом, я не знал, как записать свойства в VB:
Public Class MySession
' Private constructor (use MySession.Current to access the current instance).
Private Sub New()
End Sub
' Gets the current session.
Public Shared ReadOnly Property Current() As MySession
Get
Dim session As MySession = TryCast(HttpContext.Current.Session("__MySession__"), MySession)
If session = Nothing Then
session = New MySession()
HttpContext.Current.Session("__MySession__") = session
End If
Return session
End Get
End Property
' My session data goes here:
Public MyString As String
Public MyFlag As Boolean
Public MyNumber As Integer
End Class
Как насчет:-
public static class SessionVar
{
public static readonly string myVar1 = "myVar1";
public static readonly string myVar2 = "myVar2";
public static readonly string myVar3 = "myVar3";
public static readonly string myVar4 = "myVar4";
}
Это позволяет Вам использовать:-
session(SessionVar.myVar1) = something;
Я использовал классы как это для создания введенной обертки сессии/кэша. Вы, возможно, должны добавить дополнительный код к получению/устанавливанию, но я оставлю это до Вас.
internal class SessionHelper
{
private const string myVar1Key = "myvar1";
public static int MyVar1
{
get
{
return (int)System.Web.HttpContext.Current.Session[myVar1Key];
}
set
{
System.Web.HttpContext.Current.Session[myVar1Key] = value;
}
}
}
Извините за C#....
Только если те значения связаны. Иначе используйте простые константы.
Для простой вещи удаления всех ссылок строкового ключа я пошел бы с глобальными статическими/общими константами, видимыми в области действия приложения.
Иначе простая обертка со строгим контролем типов для переменных сеанса является превосходящей альтернативой, и это - намного больше благоприятного для ООП рассмотрения, что Вы получаете совместимость Обозревателя объектов и intellisense.
Единственный путь I видит, что перечислимое быть много ценности должно использоваться для индексации в массив или подобный список. Но даже затем необходимо бросить перечисление к интервалу.
Так, у Вас мог быть массив, который Вы загружаете при запуске приложения всеми своими ключами переменной сеанса и затем перечислением для индексов. Однако, учитывая, что объект Сессии происходит из HttpSessionState, который происходит из IEnumerable, необходимо смочь просто сделать цикл foreach по переменным сеанса, если Вы должны.
Я понимаю, что этот вопрос был задан некоторое время назад и "ответ" уже был выбран. Но я просто наткнулся на него. Ответ Мартина хорош. Однако, чтобы помочь любому, кто наткнётся на это в будущем, если вы действительно хотите иметь дело с Сессией, прочтите этот пост . Не думаю, что вы найдете что-то проще.