分類
网站

使用 Django Q 方便地執行耗時任務

Django Q 是一個使用 Python 多進程製作的原生 Django 任务队列、调度器和 worker 应用。它具有很多優異特性但我只是粗淺使用了如下幾點:

  • 多進程 worker 池
  • 異步任務
  • 定時任務、cron 和重複的任務
  • 把失敗和成功結果保存到數據庫或緩存
  • 自動集成到 Django Admin,就可以在後臺添加和管理任務
  • 支持 Redis, Disque, IronMQ, SQS, MongoDB 或 ORM 這麼多種隊列代理方式,最方便的當然是 ORM
  • 注意:Django Q 的任務間隔粒度是 30 秒,如果你的任務頻率或精準度要求高於 30 秒,你需要嘗試修改源碼或使用其他任務隊列

安裝 Django Q

pip install django-q
#如果要使用 cron 規則,則也要安裝
pip install croniter
#在項目的 settings.py 文件 INSTALLED_APPS 裏加入 django_q
INSTALLED_APPS = (
    # other apps
    'django_q',
)
#設置代理方式,我選擇 ORM,
#只需把下面字段也加入 settings.py

#更多設置請參見 https://django-q.readthedocs.io/en/latest/configure.html
Q_CLUSTER = {
    'name': 'djangtasks',
    'workers': 2,
    'timeout': 180,
    'retry': 200,
    'queue_limit': 50,
    'bulk': 10,
    'orm': 'default'
}

#執行數據庫遷移來創建數據庫表
python manage.py migrate
#運行 Django Q 來處理任務隊列
python manage.py qcluster

我是使用 screen 來在後臺運行 qcluster,很方便的。

使用 Django Q 在 Django 後臺執行耗時任務

# file: views.py
import datetime
from django.http import HttpResponse
from django.utils import timezone
from django_q.tasks import async_task, schedule
from django_q.models import Schedule

def a_longtime_task(arg):
    time.sleep(30)
    return arg

def scheduled_task(arg):
    time.sleep(30)
    return arg

def a_longtime_task_request(request):
    #立即在後臺執行
    async_task(a_longtime_task,'args for the function')
    return HttpResponse('The longtime task has been started.')

def another_longtime_task_request(request):
    #三分鐘後執行
    schedule('YOURAPP.views.scheduled_task',
            'args for the function',
            schedule_type=Schedule.ONCE,
            next_run=timezone.now() + datetime.timedelta(minutes=3))
    return HttpResponse('The task has been scheduled.')

在 Django Admin 佈置定時任務

這個就比較直接,比如要每天 10 點都執行上面例子中的 scheduled_task,就點擊 Admin 頁面 Scheduled tasks 旁邊的「新增」。

Func(填入完整的函數路徑):YOURAPP.views.scheduled_task
Args:'args for the function'
Schedule Type:Daily
Next Run(設置要運行的時間如):2022-08-27 10:00

最後點擊「儲存」就可以了。

同樣的,如果選擇 Cron 類型,就需要在 Cron 輸入框填入 Cron 計劃。比如在 9 點到 23 點期間,每 5,15,25,35,45,55 各執行一次:
5,15,25,35,45,55 9-23 * * *
更多 Cron 用法和組合可以參考 crontab.guru 這個網站。

等待執行的任務、失敗的任務和成功的任務都可以方便的在Admin頁面查看和操作,非常方便。

管理隊列任務與已完成任務 Schedule Task

# file: tasks.py
from django_q.models import Schedule, Task
from django.db.models import Q
#your model to be checked
from app1.models import Race
from django.utils import timezone

import datetime
import operator
from functools import reduce

# Task to delete successful old tasks
def delete_old_tasks():
    len_task_20 = 0
    len_task_gen = 0
    now = datetime.datetime.now()
    days_passed_2 = timezone.utc.localize(now - datetime.timedelta(days=2))
    days_passed_7 = timezone.utc.localize(now - datetime.timedelta(days=7))
    task_q_list = []
    task_q_list.append(Q(group__startswith='20'))
    task_q_list.append(Q(started__lt=days_passed_7))
    task_q_list.append(Q(success__exact=True))
    task_20_queryset = Task.objects.filter(reduce(operator.and_, task_q_list))
    len_task_20 = len(task_20_queryset)
    for task in task_20_queryset:
        task.delete()

    task_q_list = []
    task_q_list.append(Q(group__exact='generate_0_task'))
    task_q_list.append(Q(started__lt=days_passed_2))
    task_q_list.append(Q(success__exact=True))
    task_gen_queryset = Task.objects.filter(reduce(operator.and_, task_q_list))
    len_task_gen = len(task_gen_queryset)
    for task in task_gen_queryset:
        task.delete()

    return f'{len_task_20} checked tasks and {len_task_gen} checking tasks have been removed.'

#generate 0 task every 5 minuts
def generate_0_task():
    res=[]
    now = datetime.datetime.now()
    dto_now = timezone.utc.localize(now)
    start_datetime_6 = now + datetime.timedelta(minutes=6)
    dto_plus6 = timezone.utc.localize(start_datetime_6)
    current_races = Race.objects.filter(post_time_live__lte=dto_plus6,
                                          post_time_live__gte=dto_now)
    if len(current_races) == 0:
        res.append('no current races')
        return res
    for race in current_races:
        if race.race_conditions.find('SIMULCAST')>-1:
            res.append(str(race)+': task passed SIMULCAST')
            continue
        tasks = Schedule.objects.filter(name=str(race))
        if len(tasks)==0:
            schedule('app1.views.zero_mtp_task',
                    race.id, race.track_id, race.race_number, race.race_date, race.post_time_live.isoformat(),
                    schedule_type=Schedule.ONCE,
                    next_run=race.post_time_live,
                    name=str(race))
            res.append(str(race)+': task added'+' post time:'+str(race.post_time_live))
        else:
            res.append(str(race)+': task already added'+' post time:'+str(race.post_time_live))
    return res

本文更新於 2023/01/27。

分類
网站

Django with PostgreSQL

參考 PostgreSQL:Linux downloads (Red Hat family) 來安裝PostgreSQL,比如 Fedora 35 可以這樣:

sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/F-35-x86_64/pgdg-fedora-repo-latest.noarch.rpm
sudo dnf install -y postgresql13-server libpq-devel
sudo /usr/pgsql-13/bin/postgresql-13-setup initdb
sudo systemctl enable postgresql-13
sudo systemctl start postgresql-13

安裝完成後來初始化一個數據庫和用戶。

#使用 root 登錄 PostgreSQL
sudo -u postgres psql
#創建數據庫
CREATE DATABASE project;
#創建新用戶
CREATE USER user42 WITH PASSWORD 'password42';
#下面這三行優化是 Django 推薦的
ALTER ROLE user42 SET client_encoding TO 'utf8';
ALTER ROLE user42 SET default_transaction_isolation TO 'read committed';
ALTER ROLE user42 SET timezone TO 'Asia/Taipei';
#把數據庫授權給新用戶
GRANT ALL PRIVILEGES ON DATABASE project TO user42;
#退出數據庫
\q

要在 Django 中使用 PostgreSQL 數據庫,需要還安裝 psycopg2:

pip install Django psycopg2
#如果像我一樣在 Fedora 安裝失敗了
#可以嘗試安裝編譯好的版本
pip install Django psycopg2-binary

之後在項目的設置中把默認的 SQLite 數據庫資料改成 PostgreSQL 就可以了。更像詳細的步驟與解釋,可以參考:How To Use PostgreSQL with your Django Application on Ubuntu 20.04

刪除 Django 數據庫中的表格並重建

這似乎不是正確的回滾數據庫的操作辦法,但是也可以一試。

#從 migrations 目錄找到要刪除的數據庫變更文件,刪除掉
#進入數據庫操作程序
python manage.py dbshell
#查看並找到要刪除的表名
SELECT * FROM pg_catalog.pg_tables;
#如果是MariaDB,這樣查看表名
show tables;
#比如表名爲 task_day,則這樣刪除
DROP TABLE task_day;
#退出數據庫操作程序
exit;
#刪掉數據庫裏的 migrations
python manage.py migrate --prune task

#現在可以重新建立表格了
python manage.py makemigrations
python manage.py migrate

本文更新於 2022/10/24。

分類
Linux 软件

Fedora 35 與 Nvidia GPU 驅動

TL;NR

如果電腦開啓了 Secure Boot, 又不想頭痛地處理簽名,可以關掉。然後跟隨這個網頁的方法安裝開源的 Nvidia 驅動: Howto/NVIDIA。或者跟隨這個網頁安裝 Nvidia 官方的驅動:Fedora 36/35/34 NVIDIA [515.57 / 510.73.05 / 470.129.06 / 390.151 / 340.108] Drivers Install Guide。這個網頁裏也有介紹如果禁用 Fedora 自帶的 Nouveau 驅動的方法。

The Story

打算嘗試在 Fedora 上編輯視頻,一番搜索後發現 DaVinci Resolve 好像很強大,而且還有 Linux 的免費版本。下載安裝很順利,但是打開後歡迎頁面是黑屏。禁用 Secure Boot 裝了 rpmfusion 推薦的驅動後可以打開了,但是 GPU 設置成 CUDA 模式提示無法渲染圖像,錯誤編碼 999,改成 OpenGL 模式不報錯,但是連 JPG 圖像的預覽都是花的,我以爲是 rpmfusion 的驅動不行(實際不是)。於是去裝官網驅動,禁用了 Nouveau 驅動後安裝成功,但是 DaVinci 還是無法使用,後來發現可能是筆記本自動選擇顯卡 Optimus 有關,可以參考 OptimusHow to Set Nvidia as Primary GPU on Optimus-based Laptops。我並沒有把 Nvidia 設置爲默認,因爲覺得平常板載就夠了。所以後來我使用環境變量的方法成功運行了 DaVinci Resolve

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia /opt/resolve/bin/resolve

最後我發現相機拍攝的 mov 視頻文件導入後還是只有音頻,想要編輯的話要先對視頻進行轉碼。而且導出格式也有蠻多限制,所以就放棄了 DaVinci Resolve。

然後我搜索到 Linux 平臺另一款「強大」的視頻編輯器 Lightworks,到官網下載免費版體驗,發現需要註冊,註冊時發現有 recaptcha 人機驗證,我換了好幾個網絡居然都無法通過。無奈從網上找了個安裝包,安裝後打開軟件發現需要登錄才能使用所以還是要註冊。最後是第二天在手機瀏覽器裏註冊成功了。然後發現導出 1080p 的視頻居然是付費版本才有的功能,2022年了喂~

最後我去看 Fedora 的手冊,上面推薦 Kdenlive,從官網直接下載 AppImage 檔直接運行,視頻和圖片都順利導入,導出也都沒有什麼限制,h264、h265、ProRes 全都 OK!而且也支持視頻穩定和關鍵幀調整。雖然兩個視頻漸變過度的 Mixes 操作很怪異,但是至少能達到想要的效果。時間軸的操作可能由於還不會用,所有也感覺不太順手,但是至少可以正常導入、剪輯、調整顏色、加字幕和出片了。

分類
软件

Anuto TD 一個塔防遊戲

Anuto TD 是一款製作精良的塔防遊戲,它「浪費」了我很多時間!

分類
說說

220518

Emanon 今天跟我講。上週在市場買菜的時候,在一家沒去過幾次的菜攤買完菜後,順嘴問了一句,你家有青皮蕉嗎?對方說,下次有。結果今天去買菜,買完後店家問她,要不要看看我家的青皮蕉。這個事情讓她想起當年在上海,她和朋友在路上遇到一個擺路邊攤賣碟的,她朋友就隨口問了一個碟,那人表示現在沒有。後來過來一段時間,無意經過那裏的時候,那位攤主很開心叫住她說,你上次說的那張碟我給你找來咯!Emanon 和她朋友都很驚奇,因爲只是隨口這麼一問,根本沒想到對方會認真對待,並且記住了朋友的模樣。不由的會想,這事要是在東北,即使你去一家正規商店跟對方拜託好,說的很決絕,一定給你找來,可能轉身就會忘。因爲當年東北的市場不是自由市場,處處洋溢着權力氣息——售貨員沒有義務,潛在的顧客也沒有權力,來促成這筆交易。社會上的大家表面上親如兄弟,這是我的誰誰誰,實際上可能都沒把對方放在眼裏。僅有的一點信任,是斷然不能給予陌生人的。話說的有點重,但這就是當年印象。

分類
Linux

Fedora 35 安裝 VirtualBox

沒想到給 Fedora 35 安裝 VirtualBox 會遇到這麼一個坑,所以記錄下。如果你的電腦沒有啓用 EFI Secure Boot 應該不會遇到這個問題。報錯信息如下:

vboxdrv.sh: failed: modprobe vboxdrv failed. Please use 'dmesg' to find out why.

There were problems setting up VirtualBox.  To re-start the set-up process, run
  /sbin/vboxconfig
as root.  If your system is using EFI Secure Boot you may need to sign the
kernel modules (vboxdrv, vboxnetflt, vboxnetadp, vboxpci) before you can load
them. Please see your Linux system's documentation for more information.

如果你不想關閉安全啓動,那麼可以按如下步驟來解決:

1, 安裝 mokutil

sudo dnf update
sudo dnf install mokutil

2, 在新文件夾裏創建 RSA 密鑰

sudo -i
mkdir /root/signed-modules
cd /root/signed-modules
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=VirtualBox/"
chmod 600 MOK.priv

3, 準備導入密鑰的密碼,等下重啓電腦後會詢問你設置的密碼。

sudo mokutil --import MOK.der

4, 重啓電腦,電腦會進入一個藍屏,選擇 Enroll MOK --> Continue --> 輸入你剛剛設置的密碼,然後你的電腦會重啓。

5, 進入剛剛的文件夾新建一個腳本。

cd /root/signed-modules
nano sign-virtual-box

腳本內容如下:

#!/bin/bash

for modfile in $(dirname $(modinfo -n vboxdrv))/*.ko; do
  echo "Signing $modfile"
  /usr/src/kernels/$(uname -r)/scripts/sign-file sha256 \
                                /root/signed-modules/MOK.priv \
                                /root/signed-modules/MOK.der "$modfile"
done

如果腳本執行失敗了,可以嘗試運行下面命令,然後根據結果修改上面腳本。

find /usr/src -name signfile

5, 爲腳本增加執行權限並運行。

chmod 700 sign-virtual-box
./sign-virtual-box 

6, 把簽名後的驅動加入內核中就可以了。

modprobe vboxdrv

Ubuntu 用戶可以參考這篇 https://stegard.net/2016/10/virtualbox-secure-boot-ubuntu-fail/。以上解決辦法由 Younes LAB 作答與 Sign virtual box modules (vboxdrv, vboxnetflt, vboxnetadp, vboxpci) Centos 8 - Stack Overflow


從 VirtualBox RPM 源安裝 VirtualBox

由於之前沒有搜到上面的辦法,還以爲是安裝的問題,嘗試了從 VirtualBox RPM 源安裝 VirtualBox,其實是不能解決問題的,但是這裏也記錄一下。

1, 安裝依賴。

sudo dnf -y install @development-tools
sudo dnf -y install kernel-headers kernel-devel dkms elfutils-libelf-devel qt5-qtx11extras

2, 添加VirtualBox RPM 源。

Fedora 36 / Fedora 35:

cat <<EOF | sudo tee /etc/yum.repos.d/virtualbox.repo 
[virtualbox]
name=Fedora $releasever - $basearch - VirtualBox
baseurl=http://download.virtualbox.org/virtualbox/rpm/fedora/35/\$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://www.virtualbox.org/download/oracle_vbox.asc
EOF

Fedora 34:

cat <<EOF | sudo tee /etc/yum.repos.d/virtualbox.repo 
[virtualbox]
name=Fedora $releasever - $basearch - VirtualBox
baseurl=http://download.virtualbox.org/virtualbox/rpm/fedora/34/\$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://www.virtualbox.org/download/oracle_vbox.asc
EOF

Fedora 33:

cat <<EOF | sudo tee /etc/yum.repos.d/virtualbox.repo 
[virtualbox]
name=Fedora $releasever - $basearch - VirtualBox
baseurl=http://download.virtualbox.org/virtualbox/rpm/fedora/33/\$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://www.virtualbox.org/download/oracle_vbox.asc
EOF

3, 導入 VirtualBox GPG 密鑰,確認指紋匹配後按 y。

sudo dnf search virtualbox
Fedora  -  - VirtualBox                                 58  B/s | 181  B     00:03
Fedora  -  - VirtualBox                                906  B/s | 1.7 kB     00:01
Importing GPG key 0x98AB5139:
 Userid     : "Oracle Corporation (VirtualBox archive signing key) <[email protected]>"
 Fingerprint: 7B0F AB3A 13B9 0743 5925 D9C9 5442 2A4B 98AB 5139
 From       : https://www.virtualbox.org/download/oracle_vbox.asc
Is this ok [y/N]: y

4, 安裝 VirtualBox。

sudo dnf install VirtualBox-6.1

5, 把當前用戶添加到 vboxusers 用戶組。

sudo usermod -a -G vboxusers $USER
newgrp vboxusers

然後就可以通過命令 virtualbox 或應用菜單 》System 》Oracle VM VirtualBox來啓動了。但是這個時候還沒有裝 Extension Pack,表現爲虛擬機只支持 USB 1.1,屏幕無法縮放。好在擴展包直接從官網下載就可以,然後直接雙擊就能順利運行安裝。

此安裝教程來自 How To Install VirtualBox 6 on Fedora 36/35/34/33/32 - ComputingForGeeks

分類
讀書

《金魚文明》第十一章 戰鬥與修復

金魚文明

——注意力經濟如何操縱我們的網絡生活

作者:[法]布呂諾·帕蒂諾(Bruno Patino)

譯者:劉星馳

ISBN:978-7-5115-6925-7

人民日報出版社


四場戰鬥


打擊錯誤認識,而不是盲目開戰。互聯網巨頭孕育的第一個錯誤認知,源自初期自由主義意識形態和短期經濟利益的碰撞。這個認知提出,數字發展帶來的社會和經濟紊亂都可進行自我調節,就像「看不見的手」一樣。在實操層面上,它強調「自我約束」。然而,想要上市公司自覺自愿地將社會福社「內化」爲其戰略決策,並爲了社會共榮而減少盈利,這簡直是癡人說夢。相反地,近期的事件顯示,聯合起來對互聯網巨頭施壓,並發表聲明是行之有效的做法。

在國家、歐洲甚至是世界範圍內進行協商是着實可能的。迄今爲止,討論都是圍繞收入的再分配展開的。稅收當然是再分配的手段之一,在尊重著作權的前提下直接向創作者支付酬勞也可達到目的。調控甚至可以包括時間的再分配,這一點並沒有它聽上去的那麼虛無縹緲。首先,在現實生活中已經有類似案例了,如賭場限制那些太過脆弱的客人進入,並規定了最低年齡限制。其次,從長遠來看,網絡巨頭們有必要確保自己尚且年輕的產業結構,不會摧毀它們和用戶們建立起來的中長期聯繫。網癮、潛在的抑鬱症風險和疲勞感等症狀,會逐漸成爲所有用戶的問題,並進入大衆意識,這一定會讓人們對社交平台的基礎價值提出質疑。限制數字平台用算法和界面這些「大腦黑客」搜取用戶注意力,等於讓它們用短期經濟利益來換取更長久的發展。

就注意力搜取算法的應用規範進行協商。把集體干預的重點放在與平台息息相關的事務上,要避免限制過多,以維護網絡的自由。我們應該優先考慮三個方面。

首先,有一些算法的編寫目的是最大程度地提高信息的經濟效率,並且爲那些能夠引起憤怒和情緒反應的內容增加曝光度。行動的第一步,就是要讓這些算法的工作方式更透明,接着是限制其運用範圍。

其次,「暗黑模式設計」等互動界面能夠培養用戶的成癮行爲。而 2025 年之前即將湧現出來比智能手機更隱蔽的工具,還可能繼續改變人機互動的性質。因此,強制建立一個「健康的」符合倫理的人機互動形式可能是公共衛生事業的必要舉措。

最後,限制注意力廣告邏輯在平台內部的應用範圍。眼下,這些廣告覆蓋了所有的網頁和服務。傳統媒體在發展過程中嚴格地區分了廣告內容與新聞及其他的編輯建議內容。而且,各國都制定了約束廣告信息的規則(其中包括美國。從 1920 年起,美國在消費者協會的壓力下制定了廣播業廣告規範)。

思考網絡平台的法律規範,以擺脫讓社交平台擁有豁免權的美國模式。適度定義平台商的責任是一條漫長、艱難而曲折的道路,要想在所有網絡服務和內容上都實行無疑是不可能的,但是起碼這種願景是存在的。並且,嘲雜的討論已經開始了。

談到新聞,如果不給新聞業撥款,就無法實現法律責任所要求的可靠性。在這一點上,我們可以和新聞媒體及其編輯人員商討一個新的談判框架。

開發不與注意力經濟掛鈎的數字產品。這些舉措不能僅限於蒂姆·伯納斯·李提出的重要的「反互聯網」項目。「公共」社交網絡這一雄心勃勃的主張已經得到了美國某些大學的支持(如麻省理工學院媒體實驗室的公民媒體中心)。這讓人回想起 20 世紀初歐洲在視聽媒體領域採取的舉措:BBC 的成立就是爲了避免媒體受個人利益和廣告市場所主導。不過,通過鼓勵平台開發「發現型」和「解放型」的算法,我們也可以採取一些收效更快,十分有用的小規模行動。「綠色」人工智能是通往「反互聯網」的另一條道路。這樣的話,我們就有可能打造一個既野心勃勃、又可實現的工業化科技項目,而不是「歐洲 Google」或者「歐洲 Facebook」一類的幻想。

在這一點上,大衆媒體可以起到關鍵作用。由於沒有被廣告商收買,且忠誠於它們的普世使命,它們能夠且應當向網絡平台貢獻經過核實的另類信息,讓大家能夠在純粹的注意力邏輯中「停下腳步」。它們要在平台的信息輸出中「反輸出」成爲網絡政權中的抗衡勢力。另外,它們提供的另類選項能夠給構建與注意力經濟邏輯背道而馳的技術工具提供機會。開發歡迎新觀點、新文化領域、新敘事模式的算法;控制兒童和成人的上網時間,設置防沉迷提醒;開發讓人放鬆、而非充滿挑逗的互動界面;把提醒降到最低;提供前期時間投入多的節目(紀錄片、創意作品);降低音量,阻止頻閃效應……可做的事情還有很多。

四個處方


一種新型的智慧、新型的自由嘗試已經顯露頭角。當然,數字化帶來的分裂仍然存在。不過,即將到來的不平等卻發生了變化:聯網不再是目的,斷網才是。相比音樂,寧靜更重要,相比交流,冥想更可貴;相比即時消息,深入的思考更受推崇。關於「科技戒毒」主題的研討會數目與日俱增。修道院裡的清修從此換了性質:以前是逃離俗世來尋找上帝,現在變成了和逃離電子刺激來尋找自我。斷網是爲了重新回到現實世界,但這麼做的目的並不是人間蒸發,也不是拒絕數字社會的超凡潛力。我們僅僅需要明白一一自由來源於自律。這種自律不是禁慾,而更多的是節制,是一些說來容易做起來難的個人規則,一些頗爲實用卻難以強加於人的辦法。

庇護所。保羅·瓦萊里(Paul Valery)預言了一種未來:屆時,只有建立電波不侵的修道院,隔絕庸衆、新鮮事物以及盲從輕信的影響,世人才能夠獲得自由。這位作家的預言如今已經變成了人類文明的必需品。在學校及學術、祈告、辯論、會議等場所,建立像禁煙區一樣的「禁網區」屬於公共衛生的範疇。接收——慶祝——傳播,這個埃馬紐埃爾·萊維納斯(Emmanuel Levinas)口中的「三位一體」,將在我們戒掉網癮的那天實現。硅谷的企業家們正是因爲想清楚了這一點,才把孩子安排到了無網絡技術的教育機構。

我可以毫不費力地想象大量禁網場所的場景,簡單的告示牌提示人們:禁止電子設備妨礙我們的共同生活。在餐前和家人共處的時間交出電子設備,並讓這個舉動成爲一個簡單的社交禮儀。畢竟,手機屏幕是私密的,不以私密屏幕示人再正常不過。在校園裡限制使用手機已經成爲現實。以斯坦福大學爲例,這所孕育了數字時代、網絡平台和聯網社會的高校,已經禁止上課使用手機,並在逐步禁止電腦的使用。

我們最終的目的,是讓斷網在技術層面更易於操作,使它成爲網絡功能的一部分,即使這種做法會觸及部分人的直接經濟利益。2018 年,Facebook 公開承認,即使用戶斷開連接,它們的應用程序仍然會繼續「竊取」用戶數據。在改變這一點上,用戶仍然占據了舉足輕重的地位。

保護。不僅保護空間,也保護時間。當我們說到休息,或者像盎格魯-撤克遜人那樣談論「小短一會兒」的可能性時,重新掌控自己的生活的關鍵在於我們能否斷網,尤其是排除社交網站的和干擾。這些時間當然包括晚上和家人或朋友共處的親密時間。

我還記得在一個專業探討會上,與會者在開會之前被要求把手機放進一個籃子裡。開會是一個再平常不過的場景,每天都有成千上萬的人開會,但這個舉措執行起來卻頗爲不易。每個人都試圖找到一個好的藉口來逃脫上繳手機,我自己就是頭一個。不過,以後這種只允許接打電話而阻止聯網的籃子或者口袋應該會得到普及。不妨設想給我們的手機添加這樣一種簡單的功能:除了「飛行模式」之外,再設計一個「戒毒模式」,讓我們在特定時間之內不再被消息提醒打擾到,如何?

斷網幾天,權當休假,這種設想並不幼稚。我們確信少年兒童也需要這種假期,而且他們無疑比成年人更需要,這並不是白日夢。社交網站必須下決心給它們的互動頁面加入一個「退出」幾天甚至幾周的功能。比如說每周兩天或每年兩個月,平台的互動頁面可以主動鼓勵休假:「您好,您近期似乎經常使用 Facebook。我考慮在接下來幾天之內停止與您互動,您同意嗎?我將通知您的好友。」然而,現狀卻和這種想法形成鮮明的對比。用戶哪怕只減少一點社交平台的使用,就會遭到威脅性的消息轟炸(發生了什麼?)讓人焦慮的提醒(您知道您正在錯過多少好友動態嗎?)技術清除的威脅(您有丟失偏好設置的風險),與此同時,用戶的個人數據仍然在被存儲、利用、變現。

解釋。已經進入校園的社交網站,也可以走出校園。與此同時,我們需要教會學生如何正確使用它們、避開它們的不良影響、認識它們的成癮機制和對抗辦法,以及網站的病毒性傳播邏輯。闡述網上發生的事情和現實生活之間的連續性,能夠幫助年輕人意識到一點:那些看似虛擬的事情(開玩笑、騷擾等)不會只局限於虛擬世界。

減速。重新奪回時間,找回不受打擾、無電子刺激的片刻寧靜,就能夠形成一個良性循環。類似 SOL(「不如讀書吧?」,旨在強制在校學生每天閱讀半個小時)之類的運動,肩負着走出試驗階段,成爲集體工具的使命。我們的社會模式是基於加速構建起來的。因此,在任何領域(如信息、媒體、線上或者線下,甚至是消費領域)的減速舉措,都是一種抵抗手段,也是促進解放的手段。